@gamepark/skyrift 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/dist/Deck.d.ts +2 -1
  2. package/dist/Deck.js +2 -1
  3. package/dist/Memory.d.ts +1 -1
  4. package/dist/Memory.js +1 -1
  5. package/dist/SkyriftRules.d.ts +32 -63
  6. package/dist/SkyriftRules.js +40 -71
  7. package/dist/SkyriftSetup.js +4 -2
  8. package/dist/material/Card.d.ts +16 -0
  9. package/dist/material/Card.js +16 -0
  10. package/dist/material/CardProperties.js +48 -16
  11. package/dist/material/CardRule.d.ts +24 -20
  12. package/dist/material/CardRule.js +48 -65
  13. package/dist/material/CardTag.d.ts +2 -1
  14. package/dist/material/CardTag.js +2 -1
  15. package/dist/material/Effect.d.ts +1 -1
  16. package/dist/material/EffectTraits.d.ts +51 -0
  17. package/dist/material/EffectTraits.js +1 -0
  18. package/dist/material/LocationType.d.ts +3 -1
  19. package/dist/material/LocationType.js +2 -0
  20. package/dist/material/MaterialType.d.ts +2 -1
  21. package/dist/material/MaterialType.js +1 -0
  22. package/dist/material/OngoingEffect.d.ts +2 -2
  23. package/dist/material/OngoingEffect.js +2 -2
  24. package/dist/material/SpecialTokenType.d.ts +3 -0
  25. package/dist/material/SpecialTokenType.js +4 -0
  26. package/dist/material/createCardRule.d.ts +3 -0
  27. package/dist/material/createCardRule.js +7 -0
  28. package/dist/material/decks/GraveHurt.d.ts +18 -0
  29. package/dist/material/decks/GraveHurt.js +19 -0
  30. package/dist/material/decks/WindSands.d.ts +18 -0
  31. package/dist/material/decks/WindSands.js +19 -0
  32. package/dist/material/decks/gravehurt/AstralHammer.d.ts +18 -0
  33. package/dist/material/decks/gravehurt/AstralHammer.js +25 -0
  34. package/dist/material/decks/gravehurt/AstralHammerEffectRule.d.ts +4 -0
  35. package/dist/material/decks/gravehurt/AstralHammerEffectRule.js +26 -0
  36. package/dist/material/decks/gravehurt/CallOfTheEclipse.d.ts +17 -0
  37. package/dist/material/decks/gravehurt/CallOfTheEclipse.js +28 -0
  38. package/dist/material/decks/gravehurt/CallOfTheEclipseEffectRule.d.ts +5 -0
  39. package/dist/material/decks/gravehurt/CallOfTheEclipseEffectRule.js +11 -0
  40. package/dist/material/decks/gravehurt/CavernSkulker.d.ts +16 -0
  41. package/dist/material/decks/gravehurt/CavernSkulker.js +26 -0
  42. package/dist/material/decks/gravehurt/CavernSkulkerEffectRule.d.ts +4 -0
  43. package/dist/material/decks/gravehurt/CavernSkulkerEffectRule.js +15 -0
  44. package/dist/material/decks/gravehurt/Doom.d.ts +18 -0
  45. package/dist/material/decks/gravehurt/Doom.js +29 -0
  46. package/dist/material/decks/gravehurt/DoomEffectRule.d.ts +8 -0
  47. package/dist/material/decks/gravehurt/DoomEffectRule.js +32 -0
  48. package/dist/material/decks/gravehurt/InsatiableUmbraphage.d.ts +19 -0
  49. package/dist/material/decks/gravehurt/InsatiableUmbraphage.js +28 -0
  50. package/dist/material/decks/gravehurt/InsatiableUmbraphageEffectRule.d.ts +5 -0
  51. package/dist/material/decks/gravehurt/InsatiableUmbraphageEffectRule.js +21 -0
  52. package/dist/material/decks/gravehurt/MacabreLegion.d.ts +17 -0
  53. package/dist/material/decks/gravehurt/MacabreLegion.js +20 -0
  54. package/dist/material/decks/gravehurt/MoonFang.d.ts +17 -0
  55. package/dist/material/decks/gravehurt/MoonFang.js +20 -0
  56. package/dist/material/decks/gravehurt/Nosferatis.d.ts +20 -0
  57. package/dist/material/decks/gravehurt/Nosferatis.js +29 -0
  58. package/dist/material/decks/gravehurt/OstraVoiceOfTheSoul.d.ts +12 -0
  59. package/dist/material/decks/gravehurt/OstraVoiceOfTheSoul.js +11 -0
  60. package/dist/material/decks/gravehurt/ReturnInTime.d.ts +15 -0
  61. package/dist/material/decks/gravehurt/ReturnInTime.js +18 -0
  62. package/dist/material/decks/gravehurt/ScrabDoombird.d.ts +18 -0
  63. package/dist/material/decks/gravehurt/ScrabDoombird.js +21 -0
  64. package/dist/material/decks/gravehurt/TerrifyingSummoning.d.ts +18 -0
  65. package/dist/material/decks/gravehurt/TerrifyingSummoning.js +26 -0
  66. package/dist/material/decks/gravehurt/TerrifyingSummoningEffectRule.d.ts +5 -0
  67. package/dist/material/decks/gravehurt/TerrifyingSummoningEffectRule.js +11 -0
  68. package/dist/material/decks/gravehurt/TheGreatToady.d.ts +19 -0
  69. package/dist/material/decks/gravehurt/TheGreatToady.js +42 -0
  70. package/dist/material/decks/gravehurt/Umbraboros.d.ts +22 -0
  71. package/dist/material/decks/gravehurt/Umbraboros.js +30 -0
  72. package/dist/material/decks/gravehurt/UndeadRule.d.ts +5 -0
  73. package/dist/material/decks/gravehurt/UndeadRule.js +11 -0
  74. package/dist/material/decks/gravehurt/Whisperers.d.ts +13 -0
  75. package/dist/material/decks/gravehurt/Whisperers.js +17 -0
  76. package/dist/material/decks/gravehurt/WitchingHour.d.ts +16 -0
  77. package/dist/material/decks/gravehurt/WitchingHour.js +19 -0
  78. package/dist/material/decks/heathblade/ArcherRule.js +2 -2
  79. package/dist/material/decks/heathblade/Armada.d.ts +4 -3
  80. package/dist/material/decks/heathblade/Armada.js +5 -3
  81. package/dist/material/decks/heathblade/ArmadaEffectRule.d.ts +2 -1
  82. package/dist/material/decks/heathblade/ArmadaEffectRule.js +8 -1
  83. package/dist/material/decks/heathblade/Confluence.d.ts +2 -3
  84. package/dist/material/decks/heathblade/Confluence.js +5 -3
  85. package/dist/material/decks/heathblade/CoverOfNight.d.ts +4 -2
  86. package/dist/material/decks/heathblade/CoverOfNight.js +7 -1
  87. package/dist/material/decks/heathblade/Harvest.d.ts +4 -2
  88. package/dist/material/decks/heathblade/Harvest.js +7 -1
  89. package/dist/material/decks/heathblade/LoyalSquire.d.ts +6 -3
  90. package/dist/material/decks/heathblade/LoyalSquire.js +11 -4
  91. package/dist/material/decks/heathblade/Nightguard.js +3 -9
  92. package/dist/material/decks/heathblade/OzmaTheMage.d.ts +6 -4
  93. package/dist/material/decks/heathblade/OzmaTheMage.js +9 -3
  94. package/dist/material/decks/heathblade/PrincessLitha.d.ts +1 -2
  95. package/dist/material/decks/heathblade/PrincessLitha.js +4 -11
  96. package/dist/material/decks/heathblade/RobbinsMasterOfArms.d.ts +6 -2
  97. package/dist/material/decks/heathblade/RobbinsMasterOfArms.js +10 -1
  98. package/dist/material/decks/heathblade/Sacrifice.d.ts +7 -2
  99. package/dist/material/decks/heathblade/Sacrifice.js +19 -1
  100. package/dist/material/decks/heathblade/SoulBlade.d.ts +5 -2
  101. package/dist/material/decks/heathblade/SoulBlade.js +8 -1
  102. package/dist/material/decks/heathblade/WatchTower.d.ts +5 -3
  103. package/dist/material/decks/heathblade/WatchTower.js +10 -3
  104. package/dist/material/decks/highwave/AeliaSteadyHand.d.ts +1 -1
  105. package/dist/material/decks/highwave/AeliaSteadyHand.js +4 -1
  106. package/dist/material/decks/highwave/BoardingParty.d.ts +1 -1
  107. package/dist/material/decks/highwave/BoardingParty.js +4 -1
  108. package/dist/material/decks/highwave/BoardingPartyEffectRule.d.ts +4 -3
  109. package/dist/material/decks/highwave/BoardingPartyEffectRule.js +18 -23
  110. package/dist/material/decks/highwave/BonnyTheGunner.d.ts +0 -2
  111. package/dist/material/decks/highwave/BonnyTheGunner.js +0 -2
  112. package/dist/material/decks/highwave/CannonCardRule.d.ts +3 -0
  113. package/dist/material/decks/highwave/CannonCardRule.js +11 -10
  114. package/dist/material/decks/highwave/DarkArmageddon.d.ts +4 -2
  115. package/dist/material/decks/highwave/DarkArmageddon.js +7 -1
  116. package/dist/material/decks/highwave/DawnsDoom.d.ts +4 -2
  117. package/dist/material/decks/highwave/DawnsDoom.js +9 -1
  118. package/dist/material/decks/highwave/EyeOfSky.d.ts +2 -4
  119. package/dist/material/decks/highwave/EyeOfSky.js +5 -7
  120. package/dist/material/decks/highwave/EyeOfSkyEffectRule.d.ts +4 -4
  121. package/dist/material/decks/highwave/EyeOfSkyEffectRule.js +1 -3
  122. package/dist/material/decks/highwave/FortunesCourse.d.ts +1 -2
  123. package/dist/material/decks/highwave/FortunesCourse.js +3 -3
  124. package/dist/material/decks/highwave/GoldenApocalypse.d.ts +1 -1
  125. package/dist/material/decks/highwave/GoldenApocalypse.js +4 -1
  126. package/dist/material/decks/highwave/LongJawsSilver.d.ts +2 -3
  127. package/dist/material/decks/highwave/LongJawsSilver.js +7 -5
  128. package/dist/material/decks/highwave/OscarScullion.d.ts +4 -2
  129. package/dist/material/decks/highwave/OscarScullion.js +7 -1
  130. package/dist/material/decks/highwave/OttoFactotum.d.ts +4 -2
  131. package/dist/material/decks/highwave/OttoFactotum.js +10 -1
  132. package/dist/material/decks/highwave/RiggingRaiders.d.ts +5 -2
  133. package/dist/material/decks/highwave/RiggingRaiders.js +9 -1
  134. package/dist/material/decks/highwave/SeaScorcher.d.ts +6 -3
  135. package/dist/material/decks/highwave/SeaScorcher.js +13 -2
  136. package/dist/material/decks/highwave/SurpriseLoot.d.ts +4 -2
  137. package/dist/material/decks/highwave/SurpriseLoot.js +7 -1
  138. package/dist/material/decks/highwave/TideRover.d.ts +6 -2
  139. package/dist/material/decks/highwave/TideRover.js +15 -1
  140. package/dist/material/decks/highwave/TropicalRuffian.d.ts +1 -1
  141. package/dist/material/decks/highwave/TropicalRuffian.js +4 -1
  142. package/dist/material/decks/windsands/AbiSnakeCharmer.d.ts +13 -0
  143. package/dist/material/decks/windsands/AbiSnakeCharmer.js +15 -0
  144. package/dist/material/decks/windsands/AbiSnakeCharmerEffectRule.d.ts +8 -0
  145. package/dist/material/decks/windsands/AbiSnakeCharmerEffectRule.js +35 -0
  146. package/dist/material/decks/windsands/AncientCurse.d.ts +17 -0
  147. package/dist/material/decks/windsands/AncientCurse.js +25 -0
  148. package/dist/material/decks/windsands/Catadjinn.d.ts +14 -0
  149. package/dist/material/decks/windsands/Catadjinn.js +20 -0
  150. package/dist/material/decks/windsands/DeathTrap.d.ts +20 -0
  151. package/dist/material/decks/windsands/DeathTrap.js +38 -0
  152. package/dist/material/decks/windsands/DesertRaider.d.ts +17 -0
  153. package/dist/material/decks/windsands/DesertRaider.js +21 -0
  154. package/dist/material/decks/windsands/DuneWardrums.d.ts +12 -0
  155. package/dist/material/decks/windsands/DuneWardrums.js +14 -0
  156. package/dist/material/decks/windsands/ErgDeathslayer.d.ts +13 -0
  157. package/dist/material/decks/windsands/ErgDeathslayer.js +15 -0
  158. package/dist/material/decks/windsands/MalikShadowtracker.d.ts +18 -0
  159. package/dist/material/decks/windsands/MalikShadowtracker.js +24 -0
  160. package/dist/material/decks/windsands/Metamorph.d.ts +14 -0
  161. package/dist/material/decks/windsands/Metamorph.js +18 -0
  162. package/dist/material/decks/windsands/MushaFakir.d.ts +14 -0
  163. package/dist/material/decks/windsands/MushaFakir.js +18 -0
  164. package/dist/material/decks/windsands/OasisShaman.d.ts +13 -0
  165. package/dist/material/decks/windsands/OasisShaman.js +15 -0
  166. package/dist/material/decks/windsands/SandWalkers.d.ts +21 -0
  167. package/dist/material/decks/windsands/SandWalkers.js +30 -0
  168. package/dist/material/decks/windsands/StarlightBazaar.d.ts +15 -0
  169. package/dist/material/decks/windsands/StarlightBazaar.js +18 -0
  170. package/dist/material/decks/windsands/Vandals.d.ts +18 -0
  171. package/dist/material/decks/windsands/Vandals.js +25 -0
  172. package/dist/material/decks/windsands/WindWrath.d.ts +13 -0
  173. package/dist/material/decks/windsands/WindWrath.js +15 -0
  174. package/dist/material/decks/windsands/WindWrathEffectRule.d.ts +5 -0
  175. package/dist/material/decks/windsands/WindWrathEffectRule.js +17 -0
  176. package/dist/material/decks/windsands/WishLamp.d.ts +16 -0
  177. package/dist/material/decks/windsands/WishLamp.js +22 -0
  178. package/dist/rules/ChallengeEffectRule.d.ts +6 -0
  179. package/dist/rules/ChallengeEffectRule.js +17 -0
  180. package/dist/rules/ChallengeResponseRule.d.ts +8 -0
  181. package/dist/rules/ChallengeResponseRule.js +31 -0
  182. package/dist/rules/ChooseStartPlayerEffectRule.d.ts +6 -0
  183. package/dist/rules/ChooseStartPlayerEffectRule.js +15 -0
  184. package/dist/rules/DestroyEffectRule.d.ts +5 -2
  185. package/dist/rules/DestroyEffectRule.js +26 -3
  186. package/dist/rules/DiscardEffectRule.d.ts +5 -3
  187. package/dist/rules/DiscardEffectRule.js +17 -4
  188. package/dist/rules/DrawEffectRule.d.ts +4 -2
  189. package/dist/rules/DrawEffectRule.js +9 -6
  190. package/dist/rules/EffectRule.d.ts +3 -2
  191. package/dist/rules/EffectRule.js +9 -3
  192. package/dist/rules/EndRoundRule.js +11 -17
  193. package/dist/rules/GainPowerTokensEffectRule.d.ts +8 -0
  194. package/dist/rules/GainPowerTokensEffectRule.js +25 -0
  195. package/dist/rules/MulliganEffectRule.d.ts +7 -0
  196. package/dist/rules/MulliganEffectRule.js +19 -0
  197. package/dist/rules/PlayCardEffectRule.d.ts +9 -0
  198. package/dist/rules/PlayCardEffectRule.js +37 -0
  199. package/dist/rules/PlayCardRule.js +12 -12
  200. package/dist/rules/PlayerHelper.d.ts +9 -5
  201. package/dist/rules/PlayerHelper.js +25 -23
  202. package/dist/rules/PrepareNextRoundRule.js +6 -3
  203. package/dist/rules/PutCardUnderEffectRule.d.ts +7 -0
  204. package/dist/rules/PutCardUnderEffectRule.js +22 -0
  205. package/dist/rules/PutPowerTokenEffectRule.d.ts +4 -2
  206. package/dist/rules/PutPowerTokenEffectRule.js +24 -4
  207. package/dist/rules/ReturnCardEffectRule.d.ts +9 -0
  208. package/dist/rules/ReturnCardEffectRule.js +36 -0
  209. package/dist/rules/ReturnCardRule.d.ts +5 -3
  210. package/dist/rules/ReturnCardRule.js +18 -8
  211. package/dist/rules/RuleId.d.ts +15 -34
  212. package/dist/rules/RuleId.js +14 -33
  213. package/dist/rules/StartPlayerTurnRule.js +5 -5
  214. package/dist/rules/StashPowerTokensEffectRule.d.ts +5 -0
  215. package/dist/rules/StashPowerTokensEffectRule.js +15 -0
  216. package/dist/rules/StealCrystalEffectRule.js +3 -3
  217. package/dist/rules/StunCardRule.d.ts +4 -2
  218. package/dist/rules/StunCardRule.js +24 -19
  219. package/dist/rules/StunEffectRule.d.ts +11 -0
  220. package/dist/rules/StunEffectRule.js +45 -0
  221. package/dist/rules/SwitchSideEffectRule.d.ts +11 -0
  222. package/dist/rules/SwitchSideEffectRule.js +33 -0
  223. package/package.json +3 -3
@@ -0,0 +1,31 @@
1
+ import { isCreateItemType } from '@gamepark/rules-api';
2
+ import { CustomMoveType } from '../CustomMoveType';
3
+ import { LocationType } from '../material/LocationType';
4
+ import { MaterialType } from '../material/MaterialType';
5
+ import { Memory } from '../Memory';
6
+ import { EffectRule } from './EffectRule';
7
+ export class ChallengeResponseRule extends EffectRule {
8
+ getPlayerMoves() {
9
+ return [this.material(MaterialType.Crystal).createItem({ location: { type: LocationType.Stake } }), this.customMove(CustomMoveType.ConcedeRound)];
10
+ }
11
+ afterItemMove(move) {
12
+ if (isCreateItemType(MaterialType.Crystal)(move) && move.item.location.type === LocationType.Stake) {
13
+ this.cardRule.onChallengeAccepted?.();
14
+ return this.endEffect();
15
+ }
16
+ return [];
17
+ }
18
+ onCustomMove(move) {
19
+ if (move.type === CustomMoveType.ConcedeRound) {
20
+ this.memorize(Memory.ChallengeConceded, this.player);
21
+ this.cardRule.onChallengeDeclined?.();
22
+ const moves = this.endEffect();
23
+ const stake = this.material(MaterialType.Crystal).location(LocationType.Stake);
24
+ const stakeQuantity = stake.getQuantity();
25
+ if (stakeQuantity > 1)
26
+ moves.unshift(stake.deleteItem(stakeQuantity - 1));
27
+ return moves;
28
+ }
29
+ return super.onCustomMove(move);
30
+ }
31
+ }
@@ -0,0 +1,6 @@
1
+ import { CustomMove } from '@gamepark/rules-api';
2
+ import { EffectRule } from './EffectRule';
3
+ export declare class ChooseStartPlayerEffectRule extends EffectRule {
4
+ getPlayerMoves(): CustomMove[];
5
+ onCustomMove(move: CustomMove): import("@gamepark/rules-api").MaterialMove[];
6
+ }
@@ -0,0 +1,15 @@
1
+ import { CustomMoveType } from '../CustomMoveType';
2
+ import { Memory } from '../Memory';
3
+ import { EffectRule } from './EffectRule';
4
+ export class ChooseStartPlayerEffectRule extends EffectRule {
5
+ getPlayerMoves() {
6
+ return this.game.players.map((player) => this.customMove(CustomMoveType.ChoosePlayer, player));
7
+ }
8
+ onCustomMove(move) {
9
+ if (move.type === CustomMoveType.ChoosePlayer) {
10
+ this.memorize(Memory.NextRoundStartPlayer, move.data);
11
+ return this.endEffect();
12
+ }
13
+ return [];
14
+ }
15
+ }
@@ -1,8 +1,11 @@
1
1
  import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { DestroyEffect } from '../material/EffectTraits';
2
3
  import { EffectRule } from './EffectRule';
3
- export declare abstract class DestroyEffectRule extends EffectRule {
4
+ export declare class DestroyEffectRule extends EffectRule<DestroyEffect> {
4
5
  onRuleStart(): MaterialMove[];
5
6
  getPlayerMoves(): MaterialMove[];
6
- abstract getTargets(): Material;
7
+ getTargets(): Material;
7
8
  afterItemMove(move: ItemMove): MaterialMove[];
9
+ onCardDestroyed(): MaterialMove[];
10
+ onRuleEnd(): never[];
8
11
  }
@@ -1,21 +1,44 @@
1
1
  import { isMoveItemType } from '@gamepark/rules-api';
2
+ import { CustomMoveType } from '../CustomMoveType';
2
3
  import { LocationType } from '../material/LocationType';
3
4
  import { MaterialType } from '../material/MaterialType';
5
+ import { Memory } from '../Memory';
4
6
  import { EffectRule } from './EffectRule';
5
7
  export class DestroyEffectRule extends EffectRule {
6
8
  onRuleStart() {
7
- if (!this.getTargets().length) {
9
+ const targets = this.getTargets();
10
+ if (!targets.length) {
8
11
  return this.endEffect();
9
12
  }
13
+ if (this.cardRule.isAutoDestroy?.()) {
14
+ this.memorize(Memory.EffectCount, targets.length);
15
+ return targets.moveItems((item) => ({ type: LocationType.PlayerDiscard, player: item.id.back }));
16
+ }
17
+ this.memorize(Memory.EffectCount, this.cardRule.getDestroyCount?.() ?? 1);
10
18
  return [];
11
19
  }
12
20
  getPlayerMoves() {
13
- return this.getTargets().moveItems((item) => ({ type: LocationType.PlayerDiscard, player: item.location.player }));
21
+ const moves = this.getTargets().moveItems((item) => ({ type: LocationType.PlayerDiscard, player: item.id.back }));
22
+ if (this.cardRule.isDestroyOptional?.()) {
23
+ moves.push(this.customMove(CustomMoveType.EndEffect));
24
+ }
25
+ return moves;
26
+ }
27
+ getTargets() {
28
+ return this.cardRule.getDestroyTargets();
14
29
  }
15
30
  afterItemMove(move) {
16
31
  if (isMoveItemType(MaterialType.Card)(move) && move.location.type === LocationType.PlayerDiscard) {
17
- return this.endEffect();
32
+ return this.onCardDestroyed();
18
33
  }
19
34
  return [];
20
35
  }
36
+ onCardDestroyed() {
37
+ const remaining = this.memorize(Memory.EffectCount, (c) => c - 1);
38
+ return remaining <= 0 || !this.getTargets().length ? this.endEffect() : [];
39
+ }
40
+ onRuleEnd() {
41
+ this.forget(Memory.EffectCount);
42
+ return [];
43
+ }
21
44
  }
@@ -1,8 +1,10 @@
1
1
  import { ItemMove, MaterialMove, MoveItem } from '@gamepark/rules-api';
2
+ import { DiscardEffect } from '../material/EffectTraits';
2
3
  import { EffectRule } from './EffectRule';
3
- export declare class DiscardEffectRule extends EffectRule {
4
- discardCount: number;
5
- onRuleStart(): never[];
4
+ export declare class DiscardEffectRule extends EffectRule<DiscardEffect> {
5
+ get discardCount(): number;
6
+ onRuleStart(): MaterialMove[];
7
+ getTargets(): import("@gamepark/rules-api").Material<number, number, number>;
6
8
  getPlayerMoves(): MaterialMove[];
7
9
  afterItemMove(move: ItemMove): MaterialMove[];
8
10
  onDiscard(_move: MoveItem): MaterialMove[];
@@ -4,11 +4,24 @@ import { MaterialType } from '../material/MaterialType';
4
4
  import { Memory } from '../Memory';
5
5
  import { EffectRule } from './EffectRule';
6
6
  export class DiscardEffectRule extends EffectRule {
7
- discardCount = 1;
7
+ get discardCount() {
8
+ return this.cardRule.getDiscardCount?.() ?? 1;
9
+ }
8
10
  onRuleStart() {
9
- this.memorize(Memory.EffectCount, 0);
11
+ const targets = this.getTargets();
12
+ if (!targets.length) {
13
+ return this.endEffect();
14
+ }
15
+ if (this.cardRule.isAutoDiscard?.()) {
16
+ this.memorize(Memory.EffectCount, targets.length);
17
+ return targets.moveItems((item) => ({ type: LocationType.PlayerDiscard, player: item.location.player }));
18
+ }
19
+ this.memorize(Memory.EffectCount, this.discardCount);
10
20
  return [];
11
21
  }
22
+ getTargets() {
23
+ return this.cardRule.getDiscardTargets?.() ?? this.material(MaterialType.Card).location(LocationType.PlayerHand).player(this.player);
24
+ }
12
25
  getPlayerMoves() {
13
26
  return this.material(MaterialType.Card)
14
27
  .location(LocationType.PlayerHand)
@@ -22,8 +35,8 @@ export class DiscardEffectRule extends EffectRule {
22
35
  return [];
23
36
  }
24
37
  onDiscard(_move) {
25
- const count = this.memorize(Memory.EffectCount, (count) => count + 1);
26
- if (count >= this.discardCount) {
38
+ const remaining = this.memorize(Memory.EffectCount, (c) => c - 1);
39
+ if (remaining <= 0) {
27
40
  return this.endEffect();
28
41
  }
29
42
  return [];
@@ -1,6 +1,8 @@
1
1
  import { MaterialMove } from '@gamepark/rules-api';
2
+ import { DrawEffect } from '../material/EffectTraits';
2
3
  import { EffectRule } from './EffectRule';
3
- export declare class DrawEffectRule extends EffectRule {
4
+ export declare class DrawEffectRule extends EffectRule<DrawEffect> {
4
5
  onRuleStart(): MaterialMove[];
5
- getDrawCount(): number;
6
+ get drawingPlayer(): number;
7
+ get drawCount(): number;
6
8
  }
@@ -2,14 +2,17 @@ import { CustomMoveType } from '../CustomMoveType';
2
2
  import { EffectRule } from './EffectRule';
3
3
  export class DrawEffectRule extends EffectRule {
4
4
  onRuleStart() {
5
- const moves = this.endEffect();
6
- const drawCount = this.getDrawCount();
5
+ const moves = [];
6
+ const drawCount = this.drawCount;
7
7
  if (drawCount > 0) {
8
- moves.unshift(this.customMove(CustomMoveType.Draw, { player: this.player, quantity: drawCount }));
8
+ moves.push(this.customMove(CustomMoveType.Draw, { player: this.drawingPlayer, quantity: drawCount }));
9
9
  }
10
- return moves;
10
+ return [...moves, ...this.endEffect()];
11
11
  }
12
- getDrawCount() {
13
- return 1;
12
+ get drawingPlayer() {
13
+ return this.cardRule.getDrawPlayer?.() ?? this.player;
14
+ }
15
+ get drawCount() {
16
+ return this.cardRule.getDrawCount?.() ?? 1;
14
17
  }
15
18
  }
@@ -1,7 +1,8 @@
1
1
  import { CustomMove, MaterialMove, PlayerTurnRule } from '@gamepark/rules-api';
2
- export declare class EffectRule extends PlayerTurnRule {
2
+ import { CardRule } from '../material/CardRule';
3
+ export declare class EffectRule<T = unknown> extends PlayerTurnRule {
3
4
  get effectCardIndex(): number;
4
- get cardRule(): import("../material/CardRule").CardRule;
5
+ get cardRule(): CardRule & T;
5
6
  endEffect(): MaterialMove[];
6
7
  onCustomMove(move: CustomMove): MaterialMove[];
7
8
  onEndEffect(): MaterialMove[];
@@ -1,5 +1,6 @@
1
1
  import { PlayerTurnRule } from '@gamepark/rules-api';
2
2
  import { CustomMoveType } from '../CustomMoveType';
3
+ import { createCardRule } from '../material/createCardRule';
3
4
  import { LocationType } from '../material/LocationType';
4
5
  import { MaterialType } from '../material/MaterialType';
5
6
  import { Memory } from '../Memory';
@@ -10,7 +11,7 @@ export class EffectRule extends PlayerTurnRule {
10
11
  return this.remind(Memory.PendingEffects)[0].cardIndex;
11
12
  }
12
13
  get cardRule() {
13
- return new PlayerHelper(this.game, this.player).getCardRule(this.effectCardIndex);
14
+ return createCardRule(this.game, this.effectCardIndex);
14
15
  }
15
16
  endEffect() {
16
17
  return [this.customMove(CustomMoveType.EndEffect)];
@@ -25,7 +26,12 @@ export class EffectRule extends PlayerTurnRule {
25
26
  this.memorize(Memory.PendingEffects, (effects) => effects.slice(1));
26
27
  const pendingEffects = this.remind(Memory.PendingEffects);
27
28
  if (pendingEffects.length > 0) {
28
- return new PlayerHelper(this.game, this.player).getCardRule(pendingEffects[0].cardIndex).startEffect();
29
+ return new PlayerHelper(this.game, this.player).startEffect(pendingEffects[0]);
30
+ }
31
+ const concededBy = this.remind(Memory.ChallengeConceded);
32
+ if (concededBy !== undefined) {
33
+ this.forget(Memory.ChallengeConceded);
34
+ return [this.startPlayerTurn(RuleId.EndRound, concededBy)];
29
35
  }
30
36
  const crystalsInStake = this.material(MaterialType.Crystal).location(LocationType.Stake).getQuantity();
31
37
  if (crystalsInStake === 0) {
@@ -37,7 +43,7 @@ export class EffectRule extends PlayerTurnRule {
37
43
  return [this.startPlayerTurn(RuleId.EndPlayerTurn, currentPlayer)];
38
44
  }
39
45
  else {
40
- return [this.startPlayerTurn(RuleId.PlayCard, this.remind(Memory.CurrentPlayer))];
46
+ return [this.startPlayerTurn(RuleId.PlayCard, currentPlayer)];
41
47
  }
42
48
  }
43
49
  }
@@ -1,4 +1,5 @@
1
1
  import { PlayerTurnRule } from '@gamepark/rules-api';
2
+ import { createCardRule } from '../material/createCardRule';
2
3
  import { LocationType } from '../material/LocationType';
3
4
  import { MaterialType } from '../material/MaterialType';
4
5
  import { Memory } from '../Memory';
@@ -13,16 +14,7 @@ export class EndRoundRule extends PlayerTurnRule {
13
14
  const stake = this.material(MaterialType.Crystal).location(LocationType.Stake);
14
15
  const stakeQuantity = stake.getQuantity();
15
16
  if (stakeQuantity) {
16
- const challengeConceded = this.remind(Memory.ChallengeConceded);
17
- if (challengeConceded) {
18
- this.forget(Memory.ChallengeConceded);
19
- if (stakeQuantity > 1)
20
- moves.push(stake.deleteItem(stakeQuantity - 1));
21
- moves.push(stake.moveItem({ type: LocationType.PlayerCrystals, player: winner }, 1));
22
- }
23
- else {
24
- moves.push(stake.moveItem({ type: LocationType.PlayerCrystals, player: winner }, stakeQuantity));
25
- }
17
+ moves.push(stake.moveItem({ type: LocationType.PlayerCrystals, player: winner }, stakeQuantity));
26
18
  }
27
19
  const loserCards = this.material(MaterialType.Card)
28
20
  .location(LocationType.PlayArea)
@@ -35,19 +27,21 @@ export class EndRoundRule extends PlayerTurnRule {
35
27
  .sort((item) => item.location.x)
36
28
  .getIndexes();
37
29
  for (const cardIndex of loserCards) {
38
- const cardRule = new PlayerHelper(this.game, loser).getCardRule(cardIndex);
39
- moves.push(...cardRule.onRoundEnd(false));
30
+ const cardRule = createCardRule(this.game, cardIndex);
31
+ cardRule.onSkirmishEnd?.();
32
+ cardRule.onSkirmishLost?.();
40
33
  }
41
34
  for (const cardIndex of winnerCards) {
42
- const cardRule = new PlayerHelper(this.game, winner).getCardRule(cardIndex);
43
- moves.push(...cardRule.onRoundEnd(true));
35
+ const cardRule = createCardRule(this.game, cardIndex);
36
+ cardRule.onSkirmishEnd?.();
37
+ cardRule.onSkirmishWin?.();
44
38
  }
45
39
  const pendingEffects = this.remind(Memory.PendingEffects);
46
- if (pendingEffects.length === 0) {
47
- moves.push(this.startRule(RuleId.PrepareNextRound));
40
+ if (pendingEffects.length > 0) {
41
+ moves.push(...new PlayerHelper(this.game, this.player).startEffect(pendingEffects[0]));
48
42
  }
49
43
  else {
50
- moves.push(...new PlayerHelper(this.game, this.player).getCardRule(pendingEffects[0].cardIndex).startEffect());
44
+ moves.push(this.startRule(RuleId.PrepareNextRound));
51
45
  }
52
46
  return moves;
53
47
  }
@@ -0,0 +1,8 @@
1
+ import { MaterialMove } from '@gamepark/rules-api';
2
+ import { CardRule } from '../material/CardRule';
3
+ import { GainPowerTokenEffect } from '../material/EffectTraits';
4
+ import { EffectRule } from './EffectRule';
5
+ export declare class GainPowerTokensEffectRule extends EffectRule {
6
+ get cardRule(): CardRule & GainPowerTokenEffect;
7
+ onRuleStart(): MaterialMove[];
8
+ }
@@ -0,0 +1,25 @@
1
+ import { LocationType } from '../material/LocationType';
2
+ import { MaterialType } from '../material/MaterialType';
3
+ import { EffectRule } from './EffectRule';
4
+ export class GainPowerTokensEffectRule extends EffectRule {
5
+ get cardRule() {
6
+ return super.cardRule;
7
+ }
8
+ onRuleStart() {
9
+ const moves = [];
10
+ for (const index of this.cardRule.getGainPowerTokenTargets().getIndexes()) {
11
+ moves.push(this.material(MaterialType.PowerToken).createItem({
12
+ location: { type: LocationType.CardPowerTokens, parent: index }
13
+ }));
14
+ }
15
+ const stashCount = this.cardRule.getGainPowerTokenStashCount?.() ?? 0;
16
+ if (stashCount > 0) {
17
+ moves.push(this.material(MaterialType.PowerToken).createItem({
18
+ location: { type: LocationType.PlayerStash, player: this.player },
19
+ quantity: stashCount
20
+ }));
21
+ }
22
+ moves.push(...this.endEffect());
23
+ return moves;
24
+ }
25
+ }
@@ -0,0 +1,7 @@
1
+ import { CustomMove } from '@gamepark/rules-api';
2
+ import { DiscardEffectRule } from './DiscardEffectRule';
3
+ export declare class MulliganEffectRule extends DiscardEffectRule {
4
+ get discardCount(): number;
5
+ getPlayerMoves(): import("@gamepark/rules-api").MaterialMove[];
6
+ onCustomMove(move: CustomMove): import("@gamepark/rules-api").MaterialMove[];
7
+ }
@@ -0,0 +1,19 @@
1
+ import { CustomMoveType } from '../CustomMoveType';
2
+ import { Memory } from '../Memory';
3
+ import { DiscardEffectRule } from './DiscardEffectRule';
4
+ export class MulliganEffectRule extends DiscardEffectRule {
5
+ get discardCount() {
6
+ return Infinity;
7
+ }
8
+ getPlayerMoves() {
9
+ const moves = super.getPlayerMoves();
10
+ moves.push(this.customMove(CustomMoveType.Pass));
11
+ return moves;
12
+ }
13
+ onCustomMove(move) {
14
+ if (move.type === CustomMoveType.Pass) {
15
+ return [this.customMove(CustomMoveType.Draw, { player: this.player, quantity: this.remind(Memory.EffectCount) }), ...this.endEffect()];
16
+ }
17
+ return super.onCustomMove(move);
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { PlayCardEffect } from '../material/EffectTraits';
3
+ import { EffectRule } from './EffectRule';
4
+ export declare class PlayCardEffectRule extends EffectRule<PlayCardEffect> {
5
+ onRuleStart(): MaterialMove[];
6
+ getPlayerMoves(): MaterialMove[];
7
+ getTargets(): Material;
8
+ afterItemMove(move: ItemMove): MaterialMove[];
9
+ }
@@ -0,0 +1,37 @@
1
+ import { isMoveItemType } from '@gamepark/rules-api';
2
+ import { cardProperties } from '../material/CardProperties';
3
+ import { LocationType } from '../material/LocationType';
4
+ import { MaterialType } from '../material/MaterialType';
5
+ import { PlayerHelper } from './PlayerHelper';
6
+ import { EffectRule } from './EffectRule';
7
+ export class PlayCardEffectRule extends EffectRule {
8
+ onRuleStart() {
9
+ if (!this.getTargets().length) {
10
+ return this.endEffect();
11
+ }
12
+ return [];
13
+ }
14
+ getPlayerMoves() {
15
+ const moves = this.getTargets().moveItems((item) => ({
16
+ type: LocationType.PlayArea,
17
+ player: this.player,
18
+ id: cardProperties[item.id.front].type
19
+ }));
20
+ if (this.cardRule.isPlayCardOptional?.()) {
21
+ moves.push(...this.endEffect());
22
+ }
23
+ return moves;
24
+ }
25
+ getTargets() {
26
+ return this.cardRule.getPlayCardTargets?.() ?? this.material(MaterialType.Card)
27
+ .location(LocationType.PlayerHand)
28
+ .player(this.player);
29
+ }
30
+ afterItemMove(move) {
31
+ if (isMoveItemType(MaterialType.Card)(move) && move.location.type === LocationType.PlayArea) {
32
+ new PlayerHelper(this.game, this.player).onCardPlayed(move.itemIndex);
33
+ return this.endEffect();
34
+ }
35
+ return [];
36
+ }
37
+ }
@@ -1,6 +1,7 @@
1
1
  import { isMoveItemType, PlayerTurnRule } from '@gamepark/rules-api';
2
2
  import { CustomMoveType } from '../CustomMoveType';
3
3
  import { cardProperties } from '../material/CardProperties';
4
+ import { createCardRule } from '../material/createCardRule';
4
5
  import { LocationType } from '../material/LocationType';
5
6
  import { MaterialType } from '../material/MaterialType';
6
7
  import { Memory } from '../Memory';
@@ -25,37 +26,34 @@ export class PlayCardRule extends PlayerTurnRule {
25
26
  moves.push(powerTokensStash.moveItem({ type: LocationType.CardPowerTokens, parent: index }, 1));
26
27
  }
27
28
  }
28
- const usedEffects = this.remind(Memory.OncePerTurnEffects);
29
29
  for (const cardRule of playerHelper.cardRules) {
30
- if (cardRule.oncePerTurnEffect && !cardRule.isStunned() && !usedEffects.some((effect) => effect.cardIndex === cardRule.index)) {
30
+ if (cardRule.canActivate()) {
31
31
  moves.push(this.customMove(CustomMoveType.ActivateCard, cardRule.index));
32
32
  }
33
33
  }
34
34
  return moves;
35
35
  }
36
36
  get cardsICanPlay() {
37
- const playerHelper = new PlayerHelper(this.game);
38
37
  return this.material(MaterialType.Card)
39
38
  .location(LocationType.PlayerHand)
40
39
  .player(this.player)
41
- .index((index) => playerHelper.getCardRule(index).canBePlayed());
40
+ .index((index) => createCardRule(this.game, index).canBePlayed());
42
41
  }
43
42
  afterItemMove(move) {
44
- const moves = [];
45
43
  if (isMoveItemType(MaterialType.Card)(move) && move.location.type === LocationType.PlayArea) {
46
44
  const playerHelper = new PlayerHelper(this.game, this.player);
47
- moves.push(...playerHelper.onCardPlayed(move.itemIndex));
45
+ playerHelper.onCardPlayed(move.itemIndex);
48
46
  const pendingEffects = this.remind(Memory.PendingEffects);
49
47
  if (pendingEffects.length > 0) {
50
- return [...moves, ...playerHelper.getCardRule(pendingEffects[0].cardIndex).startEffect()];
48
+ return playerHelper.startEffect(pendingEffects[0]);
51
49
  }
52
50
  }
53
51
  if (isMoveItemType(MaterialType.Card)(move) || isMoveItemType(MaterialType.PowerToken)(move)) {
54
52
  if (this.remind(Memory.CardsPlayed, this.player).length > 0 && this.hasMorePower()) {
55
- moves.push(this.startRule(RuleId.EndPlayerTurn));
53
+ return [this.startRule(RuleId.EndPlayerTurn)];
56
54
  }
57
55
  }
58
- return moves;
56
+ return [];
59
57
  }
60
58
  onCustomMove(move) {
61
59
  if (move.type === CustomMoveType.ConcedeRound) {
@@ -64,9 +62,11 @@ export class PlayCardRule extends PlayerTurnRule {
64
62
  }
65
63
  else if (move.type === CustomMoveType.ActivateCard) {
66
64
  const cardIndex = move.data;
67
- const cardRule = new PlayerHelper(this.game, this.player).getCardRule(cardIndex);
68
- this.memorize(Memory.OncePerTurnEffects, (effects) => [...effects, { cardIndex }]);
69
- return cardRule.startEffect();
65
+ this.memorize(Memory.ActivatedCards, (cards) => [...cards, cardIndex]);
66
+ const cardRule = createCardRule(this.game, cardIndex);
67
+ cardRule.activate?.();
68
+ const pendingEffects = this.remind(Memory.PendingEffects);
69
+ return pendingEffects.length > 0 ? cardRule.startEffect(pendingEffects[0]) : [];
70
70
  }
71
71
  return [];
72
72
  }
@@ -1,14 +1,18 @@
1
- import { MaterialGame, MaterialMove, MaterialRulesPart } from '@gamepark/rules-api';
1
+ import { MaterialGame, MaterialRulesPart } from '@gamepark/rules-api';
2
2
  import { Deck } from '../Deck';
3
+ import { Card } from '../material/Card';
4
+ import { CardRule } from '../material/CardRule';
5
+ import { Effect } from '../material/Effect';
3
6
  export declare class PlayerHelper extends MaterialRulesPart {
4
7
  private player;
5
8
  constructor(game: MaterialGame, player?: Deck);
6
- getCardRule(cardIndex: number, card?: import("../material/Card").Card): import("../material/CardRule").CardRule;
7
- getPendingEffectCardRule(): import("../material/CardRule").CardRule;
9
+ getPendingEffectCardRule(): CardRule;
10
+ startEffect(effect: Effect): import("@gamepark/rules-api").MaterialMove[];
8
11
  get cardsInPlay(): import("@gamepark/rules-api").Material<number, number, number>;
9
- get cardRules(): import("../material/CardRule").CardRule[];
12
+ get cardRules(): CardRule[];
13
+ hasCard(card: Card): boolean;
10
14
  getPower(): number;
11
15
  get foe(): number;
12
16
  hasMorePower(): boolean;
13
- onCardPlayed(cardIndex: number): MaterialMove[];
17
+ onCardPlayed(cardIndex: number): void;
14
18
  }
@@ -1,8 +1,8 @@
1
1
  import { MaterialRulesPart } from '@gamepark/rules-api';
2
2
  import { sumBy } from 'es-toolkit';
3
3
  import { cardProperties } from '../material/CardProperties';
4
+ import { createCardRule } from '../material/createCardRule';
4
5
  import { CardSuit } from '../material/CardSuit';
5
- import { CardType } from '../material/CardType';
6
6
  import { LocationType } from '../material/LocationType';
7
7
  import { MaterialType } from '../material/MaterialType';
8
8
  import { OngoingEffectType } from '../material/OngoingEffect';
@@ -13,19 +13,21 @@ export class PlayerHelper extends MaterialRulesPart {
13
13
  super(game);
14
14
  this.player = player;
15
15
  }
16
- getCardRule(cardIndex, card = this.material(MaterialType.Card).getItem(cardIndex).id.front) {
17
- const Rule = cardProperties[card].rule;
18
- return new Rule(this.game, cardIndex);
19
- }
20
16
  getPendingEffectCardRule() {
21
17
  const cardIndex = this.remind(Memory.PendingEffects)[0].cardIndex;
22
- return this.getCardRule(cardIndex);
18
+ return createCardRule(this.game, cardIndex);
19
+ }
20
+ startEffect(effect) {
21
+ return createCardRule(this.game, effect.cardIndex).startEffect(effect);
23
22
  }
24
23
  get cardsInPlay() {
25
24
  return this.material(MaterialType.Card).location(LocationType.PlayArea).player(this.player);
26
25
  }
27
26
  get cardRules() {
28
- return this.cardsInPlay.getIndexes().map((index) => this.getCardRule(index));
27
+ return this.cardsInPlay.getIndexes().map((index) => createCardRule(this.game, index));
28
+ }
29
+ hasCard(card) {
30
+ return this.cardsInPlay.id((id) => id.front === card).length > 0;
29
31
  }
30
32
  getPower() {
31
33
  return sumBy(this.cardRules, (rule) => rule.getPower());
@@ -38,9 +40,7 @@ export class PlayerHelper extends MaterialRulesPart {
38
40
  }
39
41
  onCardPlayed(cardIndex) {
40
42
  this.memorize(Memory.CardsPlayed, (cards) => [...cards, cardIndex], this.player);
41
- this.memorize(Memory.OngoingEffects, (effects) => effects.filter((e) => !(e.type === OngoingEffectType.ForcedSuit &&
42
- this.material(MaterialType.Card).getItem(e.cardIndex).location.player !== this.player)));
43
- const cardRule = this.getCardRule(cardIndex);
43
+ const cardRule = createCardRule(this.game, cardIndex);
44
44
  if (!this.remind(Memory.Suit)) {
45
45
  const suit = cardProperties[cardRule.card].suit;
46
46
  if (suit === CardSuit.Day || suit === CardSuit.Night) {
@@ -48,21 +48,23 @@ export class PlayerHelper extends MaterialRulesPart {
48
48
  }
49
49
  }
50
50
  const ongoingEffects = this.remind(Memory.OngoingEffects);
51
- const deathTrap = ongoingEffects.find((e) => e.type === OngoingEffectType.DeathTrap);
52
- if (deathTrap && cardProperties[cardRule.card].type === CardType.Creature) {
53
- this.memorize(Memory.OngoingEffects, (effects) => effects.filter((e) => e.type !== OngoingEffectType.DeathTrap));
54
- this.memorize(Memory.PendingEffects, (effects) => [...effects, { cardIndex: deathTrap.cardIndex }]);
55
- return [];
51
+ const preventEffect = ongoingEffects.find(e => {
52
+ if (e.type !== OngoingEffectType.PreventEffects)
53
+ return false;
54
+ const source = createCardRule(this.game, e.cardIndex);
55
+ return source.preventEnterEffects(cardIndex);
56
+ });
57
+ if (preventEffect) {
58
+ createCardRule(this.game, preventEffect.cardIndex).onCardEnters?.(cardRule.card, this.player);
56
59
  }
57
- const moves = [];
58
- const cardsInPlay = this.material(MaterialType.Card).location(LocationType.PlayArea);
59
- for (const index of cardsInPlay.getIndexes()) {
60
- if (index !== cardIndex) {
61
- const otherCardRule = this.getCardRule(index);
62
- moves.push(...otherCardRule.onCardEnters(cardRule.card, this.player));
60
+ else {
61
+ const cardsInPlay = this.material(MaterialType.Card).location(LocationType.PlayArea);
62
+ for (const index of cardsInPlay.getIndexes()) {
63
+ if (index !== cardIndex) {
64
+ createCardRule(this.game, index).onCardEnters?.(cardRule.card, this.player);
65
+ }
63
66
  }
67
+ cardRule.onEnters?.();
64
68
  }
65
- moves.push(...cardRule.onEnters());
66
- return moves;
67
69
  }
68
70
  }
@@ -3,15 +3,18 @@ import { CustomMoveType } from '../CustomMoveType';
3
3
  import { LocationType } from '../material/LocationType';
4
4
  import { MaterialType } from '../material/MaterialType';
5
5
  import { Memory } from '../Memory';
6
+ import { createCardRule } from '../material/createCardRule';
6
7
  import { RuleId } from './RuleId';
7
8
  export class PrepareNextRoundRule extends MaterialRulesPart {
8
9
  onRuleStart() {
9
10
  const nextRoundStartPlayer = this.remind(Memory.NextRoundStartPlayer);
10
11
  const moves = [];
12
+ const allCardsInPlay = this.material(MaterialType.Card).location(LocationType.PlayArea);
13
+ const cardsToDiscard = allCardsInPlay.index((index) => !createCardRule(this.game, index).survivesSkirmish);
11
14
  for (const player of this.game.players) {
12
- const cardsInPlay = this.material(MaterialType.Card).location(LocationType.PlayArea).player(player);
13
- if (cardsInPlay.length > 0) {
14
- moves.push(cardsInPlay.moveItemsAtOnce({ type: LocationType.PlayerDiscard, player }));
15
+ const playerCards = cardsToDiscard.id((id) => id.back === player);
16
+ if (playerCards.length > 0) {
17
+ moves.push(playerCards.moveItemsAtOnce({ type: LocationType.PlayerDiscard, player }));
15
18
  }
16
19
  }
17
20
  moves.push(this.customMove(CustomMoveType.Draw, { player: nextRoundStartPlayer, quantity: 3 }));
@@ -0,0 +1,7 @@
1
+ import { CardRule } from '../material/CardRule';
2
+ import { PutCardUnderEffect } from '../material/EffectTraits';
3
+ import { EffectRule } from './EffectRule';
4
+ export declare class PutCardUnderEffectRule extends EffectRule {
5
+ get cardRule(): CardRule & PutCardUnderEffect;
6
+ onRuleStart(): import("@gamepark/rules-api").MaterialMove[];
7
+ }