@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,22 @@
1
+ import { sample } from 'es-toolkit';
2
+ import { LocationType } from '../material/LocationType';
3
+ import { EffectRule } from './EffectRule';
4
+ export class PutCardUnderEffectRule extends EffectRule {
5
+ get cardRule() {
6
+ return super.cardRule;
7
+ }
8
+ onRuleStart() {
9
+ const targets = this.cardRule.getPutCardUnderTargets();
10
+ if (!targets.length) {
11
+ return this.endEffect();
12
+ }
13
+ const randomIndex = sample(targets.getIndexes());
14
+ return [
15
+ targets.index(randomIndex).moveItem({
16
+ type: LocationType.UnderCard,
17
+ parent: this.effectCardIndex
18
+ }),
19
+ ...this.endEffect()
20
+ ];
21
+ }
22
+ }
@@ -1,8 +1,10 @@
1
1
  import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { PutPowerTokenEffect } from '../material/EffectTraits';
2
3
  import { EffectRule } from './EffectRule';
3
- export declare abstract class PutPowerTokenEffectRule extends EffectRule {
4
+ export declare class PutPowerTokenEffectRule extends EffectRule<PutPowerTokenEffect> {
4
5
  onRuleStart(): MaterialMove[];
5
6
  getPlayerMoves(): MaterialMove[];
6
- abstract getTargets(): Material;
7
+ getTargets(): Material;
7
8
  afterItemMove(move: ItemMove): MaterialMove[];
9
+ onRuleEnd(): never[];
8
10
  }
@@ -1,24 +1,44 @@
1
1
  import { isCreateItemType } from '@gamepark/rules-api';
2
2
  import { LocationType } from '../material/LocationType';
3
3
  import { MaterialType } from '../material/MaterialType';
4
+ import { Memory } from '../Memory';
4
5
  import { EffectRule } from './EffectRule';
5
6
  export class PutPowerTokenEffectRule extends EffectRule {
6
7
  onRuleStart() {
7
- if (!this.getTargets().length) {
8
+ const targets = this.getTargets();
9
+ if (!targets.length) {
8
10
  return this.endEffect();
9
11
  }
12
+ if (this.cardRule.isAutoPutPowerToken?.()) {
13
+ this.memorize(Memory.EffectCount, targets.length);
14
+ return targets.sort((item) => item.location.x).getIndexes().map((index) => this.material(MaterialType.PowerToken).createItem({
15
+ location: { type: LocationType.CardPowerTokens, parent: index }
16
+ }));
17
+ }
18
+ this.memorize(Memory.EffectCount, this.cardRule.getPutPowerTokenCount?.() ?? 1);
10
19
  return [];
11
20
  }
12
21
  getPlayerMoves() {
13
- const powerTokens = this.material(MaterialType.PowerToken);
14
22
  return this.getTargets()
15
23
  .getIndexes()
16
- .map((index) => powerTokens.createItem({ location: { type: LocationType.CardPowerTokens, parent: index } }));
24
+ .map((index) => this.material(MaterialType.PowerToken).createItem({
25
+ location: { type: LocationType.CardPowerTokens, parent: index }
26
+ }));
27
+ }
28
+ getTargets() {
29
+ return this.cardRule.getPutPowerTokenTargets?.() ?? this.material(MaterialType.Card).index(this.effectCardIndex);
17
30
  }
18
31
  afterItemMove(move) {
19
32
  if (isCreateItemType(MaterialType.PowerToken)(move) && move.item.location.type === LocationType.CardPowerTokens) {
20
- return this.endEffect();
33
+ const remaining = this.memorize(Memory.EffectCount, (c) => c - 1);
34
+ if (remaining <= 0) {
35
+ return this.endEffect();
36
+ }
21
37
  }
22
38
  return [];
23
39
  }
40
+ onRuleEnd() {
41
+ this.forget(Memory.EffectCount);
42
+ return [];
43
+ }
24
44
  }
@@ -0,0 +1,9 @@
1
+ import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { ReturnCardEffect } from '../material/EffectTraits';
3
+ import { EffectRule } from './EffectRule';
4
+ export declare class ReturnCardEffectRule extends EffectRule<ReturnCardEffect> {
5
+ onRuleStart(): MaterialMove[];
6
+ getPlayerMoves(): MaterialMove[];
7
+ getTargets(): Material;
8
+ afterItemMove(move: ItemMove): MaterialMove[];
9
+ }
@@ -0,0 +1,36 @@
1
+ import { isMoveItemType } from '@gamepark/rules-api';
2
+ import { CustomMoveType } from '../CustomMoveType';
3
+ import { LocationType } from '../material/LocationType';
4
+ import { MaterialType } from '../material/MaterialType';
5
+ import { EffectRule } from './EffectRule';
6
+ export class ReturnCardEffectRule extends EffectRule {
7
+ onRuleStart() {
8
+ const targets = this.getTargets();
9
+ if (!targets.length) {
10
+ return this.endEffect();
11
+ }
12
+ if (this.cardRule.isAutoReturn?.()) {
13
+ return targets.moveItems((item) => ({ type: LocationType.PlayerHand, player: item.id.back }));
14
+ }
15
+ return [];
16
+ }
17
+ getPlayerMoves() {
18
+ const moves = this.getTargets().moveItems((item) => ({
19
+ type: LocationType.PlayerHand,
20
+ player: item.id.back
21
+ }));
22
+ if (this.cardRule.isReturnOptional?.()) {
23
+ moves.push(this.customMove(CustomMoveType.EndEffect));
24
+ }
25
+ return moves;
26
+ }
27
+ getTargets() {
28
+ return this.cardRule.getReturnTargets?.() ?? this.material(MaterialType.Card).index(this.effectCardIndex);
29
+ }
30
+ afterItemMove(move) {
31
+ if (isMoveItemType(MaterialType.Card)(move) && move.location.type === LocationType.PlayerHand) {
32
+ return this.endEffect();
33
+ }
34
+ return [];
35
+ }
36
+ }
@@ -1,9 +1,11 @@
1
1
  import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { CardRule } from '../material/CardRule';
3
+ import { ReturnCardEffect } from '../material/EffectTraits';
2
4
  import { EffectRule } from './EffectRule';
3
- export declare abstract class ReturnCardRule extends EffectRule {
4
- isOptional: boolean;
5
+ export declare class ReturnCardRule extends EffectRule {
6
+ get cardRule(): CardRule & ReturnCardEffect;
5
7
  onRuleStart(): MaterialMove[];
6
8
  getPlayerMoves(): MaterialMove[];
7
- abstract getTargets(): Material;
9
+ getTargets(): Material;
8
10
  afterItemMove(move: ItemMove): MaterialMove[];
9
11
  }
@@ -1,22 +1,32 @@
1
1
  import { isMoveItemType } from '@gamepark/rules-api';
2
- import { CustomMoveType } from '../CustomMoveType';
3
2
  import { LocationType } from '../material/LocationType';
4
3
  import { MaterialType } from '../material/MaterialType';
5
4
  import { EffectRule } from './EffectRule';
6
5
  export class ReturnCardRule extends EffectRule {
7
- isOptional = true;
6
+ get cardRule() {
7
+ return super.cardRule;
8
+ }
8
9
  onRuleStart() {
9
- if (!this.getTargets().length) {
10
+ const targets = this.getTargets();
11
+ if (!targets.length) {
10
12
  return this.endEffect();
11
13
  }
14
+ if (this.cardRule.isAutoEffect?.()) {
15
+ return [
16
+ ...targets.moveItems((item) => ({ type: LocationType.PlayerHand, player: item.id.back })),
17
+ ...this.endEffect()
18
+ ];
19
+ }
12
20
  return [];
13
21
  }
14
22
  getPlayerMoves() {
15
- const moves = this.getTargets().moveItems({ type: LocationType.PlayerHand, player: this.player });
16
- if (this.isOptional) {
17
- moves.push(this.customMove(CustomMoveType.EndEffect));
18
- }
19
- return moves;
23
+ return this.getTargets().moveItems((item) => ({
24
+ type: LocationType.PlayerHand,
25
+ player: item.id.back
26
+ }));
27
+ }
28
+ getTargets() {
29
+ return this.cardRule.getReturnTargets();
20
30
  }
21
31
  afterItemMove(move) {
22
32
  if (isMoveItemType(MaterialType.Card)(move) && move.location.type === LocationType.PlayerHand) {
@@ -5,43 +5,24 @@ export declare enum RuleId {
5
5
  EndPlayerTurn = 4,
6
6
  EndRound = 5,
7
7
  PrepareNextRound = 6,
8
- MayChallenge = 7,
9
- Challenge = 8,
10
- LoyalSquireEffect = 102,
8
+ ChallengeEffect = 20,
9
+ ChallengeResponse = 21,
10
+ DrawEffect = 22,
11
+ DiscardEffect = 23,
12
+ DestroyEffect = 24,
13
+ StunEffect = 25,
14
+ ReturnCardEffect = 26,
15
+ PutPowerTokensEffect = 27,
16
+ StashPowerTokensEffect = 28,
17
+ GainCrystalEffect = 29,
18
+ StealCrystalEffect = 30,
19
+ PlayCardEffect = 31,
11
20
  PrincessLithaEffect = 103,
12
- RobbinsMasterOfArmsEffect = 104,
13
- OzmaTheMageEffect = 109,
14
21
  ArmadaEffect = 110,
15
- SoulBladeEffect = 111,
16
- CoverOfNightEffect = 112,
17
- SacrificeEffect = 113,
18
- WatchTowerEffect = 114,
19
- ConfluenceEffect = 115,
20
- HarvestEffect = 116,
21
- DesertRaiderEffect = 201,
22
- MetamorphEffect = 202,
23
22
  AbiSnakeCharmerEffect = 204,
24
- VandalsEffect = 206,
25
- MushaFakirEffect = 207,
26
- OasisShamanEffect = 208,
27
- SandWalkersEffect = 211,
28
- WishLampEffect = 212,
29
- StarlightBazaarEffect = 213,
30
- AncientCurseEffect = 214,
31
23
  WindWrathEffect = 215,
32
- DeathTrapEffect = 216,
33
- SeaScorcherEffect = 601,
34
- AeliaSteadyHandEffect = 602,
24
+ CavernSkulkerEffect = 302,
25
+ DoomEffect = 315,
35
26
  EyeOfSkyEffect = 603,
36
- TropicalRuffianEffect = 605,
37
- RiggingRaidersEffect = 606,
38
- OttoFactotumEffect = 607,
39
- OscarScullionEffect = 608,
40
- TideRoverEffect = 609,
41
- LongJawsSilverEffect = 610,
42
- FortunesCourseEffect = 612,
43
- DarkArmageddonEffect = 613,
44
- BoardingPartyEffect = 614,
45
- DawnsDoomEffect = 615,
46
- SurpriseLootEffect = 616
27
+ BoardingPartyEffect = 614
47
28
  }
@@ -7,43 +7,24 @@ export var RuleId;
7
7
  RuleId[RuleId["EndPlayerTurn"] = 4] = "EndPlayerTurn";
8
8
  RuleId[RuleId["EndRound"] = 5] = "EndRound";
9
9
  RuleId[RuleId["PrepareNextRound"] = 6] = "PrepareNextRound";
10
- RuleId[RuleId["MayChallenge"] = 7] = "MayChallenge";
11
- RuleId[RuleId["Challenge"] = 8] = "Challenge";
12
- RuleId[RuleId["LoyalSquireEffect"] = 102] = "LoyalSquireEffect";
10
+ RuleId[RuleId["ChallengeEffect"] = 20] = "ChallengeEffect";
11
+ RuleId[RuleId["ChallengeResponse"] = 21] = "ChallengeResponse";
12
+ RuleId[RuleId["DrawEffect"] = 22] = "DrawEffect";
13
+ RuleId[RuleId["DiscardEffect"] = 23] = "DiscardEffect";
14
+ RuleId[RuleId["DestroyEffect"] = 24] = "DestroyEffect";
15
+ RuleId[RuleId["StunEffect"] = 25] = "StunEffect";
16
+ RuleId[RuleId["ReturnCardEffect"] = 26] = "ReturnCardEffect";
17
+ RuleId[RuleId["PutPowerTokensEffect"] = 27] = "PutPowerTokensEffect";
18
+ RuleId[RuleId["StashPowerTokensEffect"] = 28] = "StashPowerTokensEffect";
19
+ RuleId[RuleId["GainCrystalEffect"] = 29] = "GainCrystalEffect";
20
+ RuleId[RuleId["StealCrystalEffect"] = 30] = "StealCrystalEffect";
21
+ RuleId[RuleId["PlayCardEffect"] = 31] = "PlayCardEffect";
13
22
  RuleId[RuleId["PrincessLithaEffect"] = 103] = "PrincessLithaEffect";
14
- RuleId[RuleId["RobbinsMasterOfArmsEffect"] = 104] = "RobbinsMasterOfArmsEffect";
15
- RuleId[RuleId["OzmaTheMageEffect"] = 109] = "OzmaTheMageEffect";
16
23
  RuleId[RuleId["ArmadaEffect"] = 110] = "ArmadaEffect";
17
- RuleId[RuleId["SoulBladeEffect"] = 111] = "SoulBladeEffect";
18
- RuleId[RuleId["CoverOfNightEffect"] = 112] = "CoverOfNightEffect";
19
- RuleId[RuleId["SacrificeEffect"] = 113] = "SacrificeEffect";
20
- RuleId[RuleId["WatchTowerEffect"] = 114] = "WatchTowerEffect";
21
- RuleId[RuleId["ConfluenceEffect"] = 115] = "ConfluenceEffect";
22
- RuleId[RuleId["HarvestEffect"] = 116] = "HarvestEffect";
23
- RuleId[RuleId["DesertRaiderEffect"] = 201] = "DesertRaiderEffect";
24
- RuleId[RuleId["MetamorphEffect"] = 202] = "MetamorphEffect";
25
24
  RuleId[RuleId["AbiSnakeCharmerEffect"] = 204] = "AbiSnakeCharmerEffect";
26
- RuleId[RuleId["VandalsEffect"] = 206] = "VandalsEffect";
27
- RuleId[RuleId["MushaFakirEffect"] = 207] = "MushaFakirEffect";
28
- RuleId[RuleId["OasisShamanEffect"] = 208] = "OasisShamanEffect";
29
- RuleId[RuleId["SandWalkersEffect"] = 211] = "SandWalkersEffect";
30
- RuleId[RuleId["WishLampEffect"] = 212] = "WishLampEffect";
31
- RuleId[RuleId["StarlightBazaarEffect"] = 213] = "StarlightBazaarEffect";
32
- RuleId[RuleId["AncientCurseEffect"] = 214] = "AncientCurseEffect";
33
25
  RuleId[RuleId["WindWrathEffect"] = 215] = "WindWrathEffect";
34
- RuleId[RuleId["DeathTrapEffect"] = 216] = "DeathTrapEffect";
35
- RuleId[RuleId["SeaScorcherEffect"] = 601] = "SeaScorcherEffect";
36
- RuleId[RuleId["AeliaSteadyHandEffect"] = 602] = "AeliaSteadyHandEffect";
26
+ RuleId[RuleId["CavernSkulkerEffect"] = 302] = "CavernSkulkerEffect";
27
+ RuleId[RuleId["DoomEffect"] = 315] = "DoomEffect";
37
28
  RuleId[RuleId["EyeOfSkyEffect"] = 603] = "EyeOfSkyEffect";
38
- RuleId[RuleId["TropicalRuffianEffect"] = 605] = "TropicalRuffianEffect";
39
- RuleId[RuleId["RiggingRaidersEffect"] = 606] = "RiggingRaidersEffect";
40
- RuleId[RuleId["OttoFactotumEffect"] = 607] = "OttoFactotumEffect";
41
- RuleId[RuleId["OscarScullionEffect"] = 608] = "OscarScullionEffect";
42
- RuleId[RuleId["TideRoverEffect"] = 609] = "TideRoverEffect";
43
- RuleId[RuleId["LongJawsSilverEffect"] = 610] = "LongJawsSilverEffect";
44
- RuleId[RuleId["FortunesCourseEffect"] = 612] = "FortunesCourseEffect";
45
- RuleId[RuleId["DarkArmageddonEffect"] = 613] = "DarkArmageddonEffect";
46
29
  RuleId[RuleId["BoardingPartyEffect"] = 614] = "BoardingPartyEffect";
47
- RuleId[RuleId["DawnsDoomEffect"] = 615] = "DawnsDoomEffect";
48
- RuleId[RuleId["SurpriseLootEffect"] = 616] = "SurpriseLootEffect";
49
30
  })(RuleId || (RuleId = {}));
@@ -11,24 +11,24 @@ export class StartPlayerTurnRule extends PlayerTurnRule {
11
11
  const moves = [];
12
12
  this.memorize(Memory.CurrentPlayer, this.player);
13
13
  this.memorize(Memory.CardsPlayed, [], this.player);
14
- this.memorize(Memory.OncePerTurnEffects, []);
14
+ this.memorize(Memory.ActivatedCards, []);
15
15
  this.forget(Memory.Suit);
16
16
  const actionCards = this.material(MaterialType.Card)
17
17
  .location(LocationType.PlayArea)
18
18
  .player(this.player)
19
19
  .filter((card) => cardProperties[card.id.front].type === CardType.Action);
20
- moves.push(...actionCards.moveItems({ type: LocationType.PlayerDiscard, player: this.player }));
20
+ moves.push(...actionCards.moveItems((item) => ({ type: LocationType.PlayerDiscard, player: item.id.back })));
21
21
  for (const cardRule of new PlayerHelper(this.game, this.player).cardRules) {
22
- moves.push(...cardRule.onPlayerTurnStart(this.player));
22
+ cardRule.onPlayerTurnStart?.();
23
23
  }
24
24
  for (const cardRule of new PlayerHelper(this.game, this.nextPlayer).cardRules) {
25
- moves.push(...cardRule.onPlayerTurnStart(this.player));
25
+ cardRule.onFoeTurnStart?.();
26
26
  }
27
27
  const stunTokens = this.material(MaterialType.StunToken).location(LocationType.CardStunTokens);
28
28
  moves.push(...stunTokens.deleteItems(1));
29
29
  const pendingEffects = this.remind(Memory.PendingEffects);
30
30
  if (pendingEffects.length > 0) {
31
- moves.push(...new PlayerHelper(this.game, this.player).getCardRule(pendingEffects[0].cardIndex).startEffect());
31
+ moves.push(...new PlayerHelper(this.game, this.player).startEffect(pendingEffects[0]));
32
32
  }
33
33
  else {
34
34
  moves.push(this.startRule(RuleId.PlayCard));
@@ -0,0 +1,5 @@
1
+ import { StashPowerTokenEffect } from '../material/EffectTraits';
2
+ import { EffectRule } from './EffectRule';
3
+ export declare class StashPowerTokensEffectRule extends EffectRule<StashPowerTokenEffect> {
4
+ onRuleStart(): import("@gamepark/rules-api").MaterialMove[];
5
+ }
@@ -0,0 +1,15 @@
1
+ import { LocationType } from '../material/LocationType';
2
+ import { MaterialType } from '../material/MaterialType';
3
+ import { EffectRule } from './EffectRule';
4
+ export class StashPowerTokensEffectRule extends EffectRule {
5
+ onRuleStart() {
6
+ const count = this.cardRule.getStashPowerTokenCount?.() ?? 1;
7
+ return [
8
+ this.material(MaterialType.PowerToken).createItem({
9
+ location: { type: LocationType.PlayerStash, player: this.player },
10
+ quantity: count
11
+ }),
12
+ ...this.endEffect()
13
+ ];
14
+ }
15
+ }
@@ -4,9 +4,9 @@ import { EffectRule } from './EffectRule';
4
4
  export class StealCrystalEffectRule extends EffectRule {
5
5
  onRuleStart() {
6
6
  const moves = this.endEffect();
7
- const opponentCrystals = this.material(MaterialType.Crystal).location(LocationType.PlayerCrystals).player(this.nextPlayer);
8
- if (opponentCrystals.length > 0) {
9
- moves.unshift(opponentCrystals.moveItem({ type: LocationType.PlayerCrystals, player: this.player }));
7
+ const foeCrystals = this.material(MaterialType.Crystal).location(LocationType.PlayerCrystals).player(this.nextPlayer);
8
+ if (foeCrystals.length > 0) {
9
+ moves.unshift(foeCrystals.moveItem({ type: LocationType.PlayerCrystals, player: this.player }));
10
10
  }
11
11
  return moves;
12
12
  }
@@ -1,9 +1,11 @@
1
1
  import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { StunEffect } from '../material/EffectTraits';
2
3
  import { EffectRule } from './EffectRule';
3
- export declare class StunCardRule extends EffectRule {
4
- stunCount: number;
4
+ export declare class StunCardRule extends EffectRule<StunEffect> {
5
5
  onRuleStart(): MaterialMove[];
6
6
  getPlayerMoves(): MaterialMove[];
7
+ stunTargets(): MaterialMove[];
7
8
  getTargets(): Material;
8
9
  afterItemMove(move: ItemMove): MaterialMove[];
10
+ onRuleEnd(): never[];
9
11
  }
@@ -1,40 +1,45 @@
1
1
  import { isCreateItemType } from '@gamepark/rules-api';
2
- import { cardProperties } from '../material/CardProperties';
3
- import { CardType } from '../material/CardType';
4
2
  import { LocationType } from '../material/LocationType';
5
3
  import { MaterialType } from '../material/MaterialType';
4
+ import { Memory } from '../Memory';
6
5
  import { EffectRule } from './EffectRule';
7
6
  export class StunCardRule extends EffectRule {
8
- stunCount = 1;
9
7
  onRuleStart() {
8
+ this.memorize(Memory.EffectCount, []);
10
9
  if (!this.getTargets().length) {
11
10
  return this.endEffect();
12
11
  }
12
+ if (this.cardRule.isAutoStun?.()) {
13
+ return this.stunTargets();
14
+ }
13
15
  return [];
14
16
  }
15
17
  getPlayerMoves() {
16
- const creatures = this.getTargets().getIndexes();
17
- const moves = [];
18
- for (const creatureIndex of creatures) {
19
- moves.push(this.material(MaterialType.StunToken).createItem({
20
- location: {
21
- type: LocationType.CardStunTokens,
22
- parent: creatureIndex
23
- },
24
- quantity: this.stunCount
25
- }));
26
- }
27
- return moves;
18
+ return this.stunTargets();
19
+ }
20
+ stunTargets() {
21
+ const stunCount = this.cardRule.getStunCount?.() ?? 1;
22
+ return this.getTargets().getIndexes().map((creatureIndex) => this.material(MaterialType.StunToken).createItem({
23
+ location: { type: LocationType.CardStunTokens, parent: creatureIndex },
24
+ quantity: stunCount
25
+ }));
28
26
  }
29
27
  getTargets() {
30
- return this.material(MaterialType.Card)
31
- .location(LocationType.PlayArea)
32
- .id((id) => cardProperties[id.front].type === CardType.Creature);
28
+ const stunned = this.remind(Memory.EffectCount);
29
+ const targets = this.cardRule.getStunTargets?.() ?? this.cardRule.creatures;
30
+ return targets.index((index) => !stunned.includes(index));
33
31
  }
34
32
  afterItemMove(move) {
35
33
  if (isCreateItemType(MaterialType.StunToken)(move) && move.item.location.type === LocationType.CardStunTokens) {
36
- return this.endEffect();
34
+ const stunned = this.memorize(Memory.EffectCount, (s) => [...s, move.item.location.parent]);
35
+ if (stunned.length >= (this.cardRule.getStunTargetsCount?.() ?? 1) || !this.getTargets().length) {
36
+ return this.endEffect();
37
+ }
37
38
  }
38
39
  return [];
39
40
  }
41
+ onRuleEnd() {
42
+ this.forget(Memory.EffectCount);
43
+ return [];
44
+ }
40
45
  }
@@ -0,0 +1,11 @@
1
+ import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { StunEffect } from '../material/EffectTraits';
3
+ import { EffectRule } from './EffectRule';
4
+ export declare class StunEffectRule extends EffectRule<StunEffect> {
5
+ onRuleStart(): MaterialMove[];
6
+ getPlayerMoves(): MaterialMove[];
7
+ stunTargets(): MaterialMove[];
8
+ getTargets(): Material;
9
+ afterItemMove(move: ItemMove): MaterialMove[];
10
+ onRuleEnd(): never[];
11
+ }
@@ -0,0 +1,45 @@
1
+ import { isCreateItemType } from '@gamepark/rules-api';
2
+ import { LocationType } from '../material/LocationType';
3
+ import { MaterialType } from '../material/MaterialType';
4
+ import { Memory } from '../Memory';
5
+ import { EffectRule } from './EffectRule';
6
+ export class StunEffectRule extends EffectRule {
7
+ onRuleStart() {
8
+ this.memorize(Memory.EffectCount, []);
9
+ if (!this.getTargets().length) {
10
+ return this.endEffect();
11
+ }
12
+ if (this.cardRule.isAutoStun?.()) {
13
+ return this.stunTargets();
14
+ }
15
+ return [];
16
+ }
17
+ getPlayerMoves() {
18
+ return this.stunTargets();
19
+ }
20
+ stunTargets() {
21
+ const stunCount = this.cardRule.getStunCount?.() ?? 1;
22
+ return this.getTargets().sort((item) => item.location.x).getIndexes().map((creatureIndex) => this.material(MaterialType.StunToken).createItem({
23
+ location: { type: LocationType.CardStunTokens, parent: creatureIndex },
24
+ quantity: stunCount
25
+ }));
26
+ }
27
+ getTargets() {
28
+ const stunned = this.remind(Memory.EffectCount);
29
+ const targets = this.cardRule.getStunTargets?.() ?? this.cardRule.creatures;
30
+ return targets.index((index) => !stunned.includes(index));
31
+ }
32
+ afterItemMove(move) {
33
+ if (isCreateItemType(MaterialType.StunToken)(move) && move.item.location.type === LocationType.CardStunTokens) {
34
+ const stunned = this.memorize(Memory.EffectCount, (s) => [...s, move.item.location.parent]);
35
+ if ((!this.cardRule.isAutoStun?.() && stunned.length >= (this.cardRule.getStunTargetsCount?.() ?? 1)) || !this.getTargets().length) {
36
+ return this.endEffect();
37
+ }
38
+ }
39
+ return [];
40
+ }
41
+ onRuleEnd() {
42
+ this.forget(Memory.EffectCount);
43
+ return [];
44
+ }
45
+ }
@@ -0,0 +1,11 @@
1
+ import { ItemMove, Material, MaterialMove } from '@gamepark/rules-api';
2
+ import { CardRule } from '../material/CardRule';
3
+ import { SwitchSideEffect } from '../material/EffectTraits';
4
+ import { EffectRule } from './EffectRule';
5
+ export declare class SwitchSideEffectRule extends EffectRule {
6
+ get cardRule(): CardRule & SwitchSideEffect;
7
+ onRuleStart(): MaterialMove[];
8
+ getPlayerMoves(): MaterialMove[];
9
+ getTargets(): Material;
10
+ afterItemMove(move: ItemMove): MaterialMove[];
11
+ }
@@ -0,0 +1,33 @@
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 { EffectRule } from './EffectRule';
6
+ export class SwitchSideEffectRule extends EffectRule {
7
+ get cardRule() {
8
+ return super.cardRule;
9
+ }
10
+ onRuleStart() {
11
+ const targets = this.getTargets();
12
+ if (!targets.length) {
13
+ return this.endEffect();
14
+ }
15
+ return [];
16
+ }
17
+ getPlayerMoves() {
18
+ return this.getTargets().moveItems((item) => ({
19
+ type: LocationType.PlayArea,
20
+ player: item.location.player === this.player ? this.nextPlayer : this.player,
21
+ id: cardProperties[item.id.front].type
22
+ }));
23
+ }
24
+ getTargets() {
25
+ return this.cardRule.getSwitchSideTargets();
26
+ }
27
+ afterItemMove(move) {
28
+ if (isMoveItemType(MaterialType.Card)(move) && move.location.type === LocationType.PlayArea) {
29
+ return this.endEffect();
30
+ }
31
+ return [];
32
+ }
33
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamepark/skyrift",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "The rules of SkyRift adapted for Game Park",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -26,9 +26,9 @@
26
26
  "es-toolkit": "^1.39.10"
27
27
  },
28
28
  "devDependencies": {
29
- "@gamepark/rules-api": "~7.2.0",
29
+ "@gamepark/rules-api": "~7.5.0",
30
30
  "es-toolkit": "^1.43.0",
31
31
  "vitest": "^4.0.15"
32
32
  },
33
- "gitHead": "f50ba0de0d312d2424e9bb27f567966975c5e72d"
33
+ "gitHead": "e9084054f7da0b172340a4a24de6f26170bd06c5"
34
34
  }