@firestone-hs/simulate-bgs-battle 1.1.540 → 1.1.543

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 (46) hide show
  1. package/dist/bgs-player-entity.d.ts +2 -1
  2. package/dist/bgs-player-entity.js.map +1 -1
  3. package/dist/cards/impl/_card-mappings.js +2 -0
  4. package/dist/cards/impl/_card-mappings.js.map +1 -1
  5. package/dist/cards/impl/hero-power/aim-high.js +8 -6
  6. package/dist/cards/impl/hero-power/aim-high.js.map +1 -1
  7. package/dist/cards/impl/hero-power/aim-left.js +7 -5
  8. package/dist/cards/impl/hero-power/aim-left.js.map +1 -1
  9. package/dist/cards/impl/hero-power/aim-low.js +8 -6
  10. package/dist/cards/impl/hero-power/aim-low.js.map +1 -1
  11. package/dist/cards/impl/hero-power/aim-right.js +7 -5
  12. package/dist/cards/impl/hero-power/aim-right.js.map +1 -1
  13. package/dist/cards/impl/hero-power/earth-invocation.js +5 -3
  14. package/dist/cards/impl/hero-power/earth-invocation.js.map +1 -1
  15. package/dist/cards/impl/hero-power/embrace-your-rage.js +15 -13
  16. package/dist/cards/impl/hero-power/embrace-your-rage.js.map +1 -1
  17. package/dist/cards/impl/hero-power/fire-invocation.js +5 -3
  18. package/dist/cards/impl/hero-power/fire-invocation.js.map +1 -1
  19. package/dist/cards/impl/hero-power/fragrant-phylactery.js +15 -13
  20. package/dist/cards/impl/hero-power/fragrant-phylactery.js.map +1 -1
  21. package/dist/cards/impl/hero-power/glorious-gloop.js +33 -28
  22. package/dist/cards/impl/hero-power/glorious-gloop.js.map +1 -1
  23. package/dist/cards/impl/hero-power/lightning-invocation.js +5 -3
  24. package/dist/cards/impl/hero-power/lightning-invocation.js.map +1 -1
  25. package/dist/cards/impl/hero-power/rapid-reanimation.js +17 -16
  26. package/dist/cards/impl/hero-power/rapid-reanimation.js.map +1 -1
  27. package/dist/cards/impl/hero-power/reborn-rites.js +10 -8
  28. package/dist/cards/impl/hero-power/reborn-rites.js.map +1 -1
  29. package/dist/cards/impl/hero-power/tentacular.js +1 -1
  30. package/dist/cards/impl/hero-power/tentacular.js.map +1 -1
  31. package/dist/cards/impl/hero-power/water-invocation.js +5 -3
  32. package/dist/cards/impl/hero-power/water-invocation.js.map +1 -1
  33. package/dist/cards/impl/hero-power/wax-warband.js +21 -19
  34. package/dist/cards/impl/hero-power/wax-warband.js.map +1 -1
  35. package/dist/cards/impl/minion/battlecruiser.js +1 -1
  36. package/dist/cards/impl/minion/battlecruiser.js.map +1 -1
  37. package/dist/simulate-bgs-battle.js +1 -1
  38. package/dist/simulate-bgs-battle.js.map +1 -1
  39. package/dist/simulation/spectator/game-sample.d.ts +1 -0
  40. package/dist/simulation/spectator/game-sample.js.map +1 -1
  41. package/dist/simulation/spectator/spectator.d.ts +2 -1
  42. package/dist/simulation/spectator/spectator.js +7 -5
  43. package/dist/simulation/spectator/spectator.js.map +1 -1
  44. package/dist/simulation/summon-when-space.js +11 -9
  45. package/dist/simulation/summon-when-space.js.map +1 -1
  46. package/package.json +1 -1
@@ -5,22 +5,23 @@ const utils_1 = require("../../../utils");
5
5
  exports.RapidReanimation = {
6
6
  startOfCombatTiming: 'pre-combat',
7
7
  startOfCombat: (trinket, input) => {
8
- if (input.playerEntity.heroPowerUsed) {
9
- const minionThatWillDie = input.playerBoard
10
- .filter((m) => m.enchantments.some((e) => e.cardId === "BG25_HERO_103pe"))
11
- .sort((a, b) => b.enchantments.find((e) => e.cardId === "BG25_HERO_103pe")
12
- .originEntityId -
13
- a.enchantments.find((e) => e.cardId === "BG25_HERO_103pe")
14
- .originEntityId || b.entityId - a.entityId)[0];
15
- if (minionThatWillDie) {
16
- const rapidReanimationIndexFromLeft = input.playerBoard.indexOf(minionThatWillDie);
17
- input.playerEntity.rapidReanimationIndexFromRight =
18
- input.playerBoard.length - 1 - rapidReanimationIndexFromLeft;
19
- const minionToCopy = (0, utils_1.copyEntity)(minionThatWillDie);
20
- input.playerEntity.rapidReanimationMinion = minionToCopy;
21
- minionThatWillDie.definitelyDead = true;
22
- input.gameState.spectator.registerPowerTarget(input.playerEntity, minionThatWillDie, input.playerBoard, input.playerEntity, input.opponentEntity);
23
- return { hasTriggered: true, shouldRecomputeCurrentAttacker: true };
8
+ for (const heroPower of input.playerEntity.heroPowers) {
9
+ if (heroPower.used) {
10
+ const minionThatWillDie = input.playerBoard
11
+ .filter((m) => m.enchantments.some((e) => e.cardId === "BG25_HERO_103pe"))
12
+ .sort((a, b) => b.enchantments.find((e) => e.cardId === "BG25_HERO_103pe")
13
+ .originEntityId -
14
+ a.enchantments.find((e) => e.cardId === "BG25_HERO_103pe").originEntityId || b.entityId - a.entityId)[0];
15
+ if (minionThatWillDie) {
16
+ const rapidReanimationIndexFromLeft = input.playerBoard.indexOf(minionThatWillDie);
17
+ input.playerEntity.rapidReanimationIndexFromRight =
18
+ input.playerBoard.length - 1 - rapidReanimationIndexFromLeft;
19
+ const minionToCopy = (0, utils_1.copyEntity)(minionThatWillDie);
20
+ input.playerEntity.rapidReanimationMinion = minionToCopy;
21
+ minionThatWillDie.definitelyDead = true;
22
+ input.gameState.spectator.registerPowerTarget(input.playerEntity, minionThatWillDie, input.playerBoard, input.playerEntity, input.opponentEntity);
23
+ return { hasTriggered: true, shouldRecomputeCurrentAttacker: true };
24
+ }
24
25
  }
25
26
  }
26
27
  },
@@ -1 +1 @@
1
- {"version":3,"file":"rapid-reanimation.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/rapid-reanimation.ts"],"names":[],"mappings":";;;AAGA,0CAA4C;AAG/B,QAAA,gBAAgB,GAAsB;IAClD,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,IAAI,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE;YAMrC,MAAM,iBAAiB,GAAG,KAAK,CAAC,WAAW;iBACzC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACb,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,sBAAuD,CAAC,CAC3F;iBACA,IAAI,CACJ,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACR,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,sBAAuD,CAAC;iBACzF,cAAc;gBACf,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,sBAAuD,CAAC;qBACzF,cAAc,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAC7C,CAAC,CAAC,CAAC,CAAC;YACN,IAAI,iBAAiB,EAAE;gBAUtB,MAAM,6BAA6B,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;gBACnF,KAAK,CAAC,YAAY,CAAC,8BAA8B;oBAChD,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,GAAG,6BAA6B,CAAC;gBAC9D,MAAM,YAAY,GAAG,IAAA,kBAAU,EAAC,iBAAiB,CAAC,CAAC;gBAGnD,KAAK,CAAC,YAAY,CAAC,sBAAsB,GAAG,YAAY,CAAC;gBACzD,iBAAiB,CAAC,cAAc,GAAG,IAAI,CAAC;gBACxC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,KAAK,CAAC,YAAY,EAClB,iBAAiB,EACjB,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;gBACF,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;aACpE;SACD;IACF,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '@firestone-hs/reference-data';\r\nimport { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { copyEntity } from '../../../utils';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const RapidReanimation: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tif (input.playerEntity.heroPowerUsed) {\r\n\t\t\t// Getting the right enchantment can be tricky. The RapidReanimation enchantment can sometimes be\r\n\t\t\t// in the Graveyard zone, so we can't filter them out. In that case, we can have multiple\r\n\t\t\t// enchantments\r\n\t\t\t// However, because of how things are handled in the logs, we should be able to always take the one *\r\n\t\t\t// with the biggest entityId\r\n\t\t\tconst minionThatWillDie = input.playerBoard\r\n\t\t\t\t.filter((m) =>\r\n\t\t\t\t\tm.enchantments.some((e) => e.cardId === CardIds.RapidReanimation_ImpendingDeathEnchantment),\r\n\t\t\t\t)\r\n\t\t\t\t.sort(\r\n\t\t\t\t\t(a, b) =>\r\n\t\t\t\t\t\tb.enchantments.find((e) => e.cardId === CardIds.RapidReanimation_ImpendingDeathEnchantment)\r\n\t\t\t\t\t\t\t.originEntityId -\r\n\t\t\t\t\t\t\ta.enchantments.find((e) => e.cardId === CardIds.RapidReanimation_ImpendingDeathEnchantment)\r\n\t\t\t\t\t\t\t\t.originEntityId || b.entityId - a.entityId,\r\n\t\t\t\t)[0];\r\n\t\t\tif (minionThatWillDie) {\r\n\t\t\t\t// So this is a bit tricky (as all the stuff with indices...). Because in practice it's more likely that players use Rapid Reanimation\r\n\t\t\t\t// on minions that they want to die quickly, most of the time they will be placed\r\n\t\t\t\t// to the left of the board\r\n\t\t\t\t// So using a left-based index (usually 0) is more likely to be correct after minions spawn on the board\r\n\t\t\t\t// Update: this looks like it's not the case, and looking at\r\n\t\t\t\t// http://replays.firestoneapp.com/?reviewId=2e6b389f-d904-43a2-a7cd-928a60d973ce&turn=11&action=1\r\n\t\t\t\t// the index seems to be right-based at least in some cases\r\n\t\t\t\t// Looks like even this is wrong:\r\n\t\t\t\t// http://replays.firestoneapp.com/?reviewId=9a46ab39-ccf0-478c-a010-68f2abb06c6f&turn=9&action=0\r\n\t\t\t\tconst rapidReanimationIndexFromLeft = input.playerBoard.indexOf(minionThatWillDie);\r\n\t\t\t\tinput.playerEntity.rapidReanimationIndexFromRight =\r\n\t\t\t\t\tinput.playerBoard.length - 1 - rapidReanimationIndexFromLeft;\r\n\t\t\t\tconst minionToCopy = copyEntity(minionThatWillDie);\r\n\t\t\t\t// We don't reapply auras when resummoning\r\n\t\t\t\t// removeAurasFromSelf(minionToCopy, input.playerBoard, input.playerEntity, input.gameState);\r\n\t\t\t\tinput.playerEntity.rapidReanimationMinion = minionToCopy;\r\n\t\t\t\tminionThatWillDie.definitelyDead = true;\r\n\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tminionThatWillDie,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t);\r\n\t\t\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true };\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"rapid-reanimation.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/rapid-reanimation.ts"],"names":[],"mappings":";;;AAGA,0CAA4C;AAG/B,QAAA,gBAAgB,GAAsB;IAClD,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE;YACtD,IAAI,SAAS,CAAC,IAAI,EAAE;gBAMnB,MAAM,iBAAiB,GAAG,KAAK,CAAC,WAAW;qBACzC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACb,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,sBAAuD,CAAC,CAC3F;qBACA,IAAI,CACJ,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACR,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,sBAAuD,CAAC;qBACzF,cAAc;oBACf,CAAC,CAAC,YAAY,CAAC,IAAI,CAClB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,sBAAuD,CACtE,CAAC,cAAc,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAC7C,CAAC,CAAC,CAAC,CAAC;gBACN,IAAI,iBAAiB,EAAE;oBAUtB,MAAM,6BAA6B,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;oBACnF,KAAK,CAAC,YAAY,CAAC,8BAA8B;wBAChD,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,GAAG,6BAA6B,CAAC;oBAC9D,MAAM,YAAY,GAAG,IAAA,kBAAU,EAAC,iBAAiB,CAAC,CAAC;oBAGnD,KAAK,CAAC,YAAY,CAAC,sBAAsB,GAAG,YAAY,CAAC;oBACzD,iBAAiB,CAAC,cAAc,GAAG,IAAI,CAAC;oBACxC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,KAAK,CAAC,YAAY,EAClB,iBAAiB,EACjB,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;oBACF,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;iBACpE;aACD;SACD;IACF,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '@firestone-hs/reference-data';\r\nimport { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { copyEntity } from '../../../utils';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const RapidReanimation: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tfor (const heroPower of input.playerEntity.heroPowers) {\r\n\t\t\tif (heroPower.used) {\r\n\t\t\t\t// Getting the right enchantment can be tricky. The RapidReanimation enchantment can sometimes be\r\n\t\t\t\t// in the Graveyard zone, so we can't filter them out. In that case, we can have multiple\r\n\t\t\t\t// enchantments\r\n\t\t\t\t// However, because of how things are handled in the logs, we should be able to always take the one *\r\n\t\t\t\t// with the biggest entityId\r\n\t\t\t\tconst minionThatWillDie = input.playerBoard\r\n\t\t\t\t\t.filter((m) =>\r\n\t\t\t\t\t\tm.enchantments.some((e) => e.cardId === CardIds.RapidReanimation_ImpendingDeathEnchantment),\r\n\t\t\t\t\t)\r\n\t\t\t\t\t.sort(\r\n\t\t\t\t\t\t(a, b) =>\r\n\t\t\t\t\t\t\tb.enchantments.find((e) => e.cardId === CardIds.RapidReanimation_ImpendingDeathEnchantment)\r\n\t\t\t\t\t\t\t\t.originEntityId -\r\n\t\t\t\t\t\t\t\ta.enchantments.find(\r\n\t\t\t\t\t\t\t\t\t(e) => e.cardId === CardIds.RapidReanimation_ImpendingDeathEnchantment,\r\n\t\t\t\t\t\t\t\t).originEntityId || b.entityId - a.entityId,\r\n\t\t\t\t\t)[0];\r\n\t\t\t\tif (minionThatWillDie) {\r\n\t\t\t\t\t// So this is a bit tricky (as all the stuff with indices...). Because in practice it's more likely that players use Rapid Reanimation\r\n\t\t\t\t\t// on minions that they want to die quickly, most of the time they will be placed\r\n\t\t\t\t\t// to the left of the board\r\n\t\t\t\t\t// So using a left-based index (usually 0) is more likely to be correct after minions spawn on the board\r\n\t\t\t\t\t// Update: this looks like it's not the case, and looking at\r\n\t\t\t\t\t// http://replays.firestoneapp.com/?reviewId=2e6b389f-d904-43a2-a7cd-928a60d973ce&turn=11&action=1\r\n\t\t\t\t\t// the index seems to be right-based at least in some cases\r\n\t\t\t\t\t// Looks like even this is wrong:\r\n\t\t\t\t\t// http://replays.firestoneapp.com/?reviewId=9a46ab39-ccf0-478c-a010-68f2abb06c6f&turn=9&action=0\r\n\t\t\t\t\tconst rapidReanimationIndexFromLeft = input.playerBoard.indexOf(minionThatWillDie);\r\n\t\t\t\t\tinput.playerEntity.rapidReanimationIndexFromRight =\r\n\t\t\t\t\t\tinput.playerBoard.length - 1 - rapidReanimationIndexFromLeft;\r\n\t\t\t\t\tconst minionToCopy = copyEntity(minionThatWillDie);\r\n\t\t\t\t\t// We don't reapply auras when resummoning\r\n\t\t\t\t\t// removeAurasFromSelf(minionToCopy, input.playerBoard, input.playerEntity, input.gameState);\r\n\t\t\t\t\tinput.playerEntity.rapidReanimationMinion = minionToCopy;\r\n\t\t\t\t\tminionThatWillDie.definitelyDead = true;\r\n\t\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\tminionThatWillDie,\r\n\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true };\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n"]}
@@ -5,15 +5,17 @@ const reborn_1 = require("../../../keywords/reborn");
5
5
  exports.RebornRites = {
6
6
  startOfCombatTiming: 'pre-combat',
7
7
  startOfCombat: (trinket, input) => {
8
- if (input.playerEntity.heroPowerUsed) {
9
- const targetEntityId = input.playerEntity.heroPowerInfo;
10
- const target = input.playerBoard.find((entity) => entity.entityId === targetEntityId);
11
- if (!target || target.reborn) {
12
- return false;
8
+ for (const heroPower of input.playerEntity.heroPowers) {
9
+ if (heroPower.used) {
10
+ const targetEntityId = heroPower.info;
11
+ const target = input.playerBoard.find((entity) => entity.entityId === targetEntityId);
12
+ if (!target || target.reborn) {
13
+ return false;
14
+ }
15
+ (0, reborn_1.updateReborn)(target, true, input.playerBoard, input.playerEntity, input.opponentEntity, input.gameState);
16
+ input.gameState.spectator.registerPowerTarget(input.playerEntity, target, input.playerBoard, input.playerEntity, input.opponentEntity);
17
+ return true;
13
18
  }
14
- (0, reborn_1.updateReborn)(target, true, input.playerBoard, input.playerEntity, input.opponentEntity, input.gameState);
15
- input.gameState.spectator.registerPowerTarget(input.playerEntity, target, input.playerBoard, input.playerEntity, input.opponentEntity);
16
- return true;
17
19
  }
18
20
  },
19
21
  };
@@ -1 +1 @@
1
- {"version":3,"file":"reborn-rites.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/reborn-rites.ts"],"names":[],"mappings":";;;AACA,qDAAwD;AAI3C,QAAA,WAAW,GAAsB;IAC7C,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,IAAI,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE;YACrC,MAAM,cAAc,GAAG,KAAK,CAAC,YAAY,CAAC,aAAuB,CAAC;YAClE,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,CAAC;YACtF,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE;gBAC7B,OAAO,KAAK,CAAC;aACb;YAED,IAAA,qBAAY,EAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YACzG,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,KAAK,CAAC,YAAY,EAClB,MAAM,EACN,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;YACF,OAAO,IAAI,CAAC;SACZ;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { updateReborn } from '../../../keywords/reborn';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const RebornRites: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tif (input.playerEntity.heroPowerUsed) {\r\n\t\t\tconst targetEntityId = input.playerEntity.heroPowerInfo as number;\r\n\t\t\tconst target = input.playerBoard.find((entity) => entity.entityId === targetEntityId);\r\n\t\t\tif (!target || target.reborn) {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\r\n\t\t\tupdateReborn(target, true, input.playerBoard, input.playerEntity, input.opponentEntity, input.gameState);\r\n\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\ttarget,\r\n\t\t\t\tinput.playerBoard,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tinput.opponentEntity,\r\n\t\t\t);\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"reborn-rites.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/reborn-rites.ts"],"names":[],"mappings":";;;AACA,qDAAwD;AAI3C,QAAA,WAAW,GAAsB;IAC7C,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE;YACtD,IAAI,SAAS,CAAC,IAAI,EAAE;gBACnB,MAAM,cAAc,GAAG,SAAS,CAAC,IAAc,CAAC;gBAChD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,cAAc,CAAC,CAAC;gBACtF,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE;oBAC7B,OAAO,KAAK,CAAC;iBACb;gBAED,IAAA,qBAAY,EACX,MAAM,EACN,IAAI,EACJ,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,KAAK,CAAC,YAAY,EAClB,MAAM,EACN,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;gBACF,OAAO,IAAI,CAAC;aACZ;SACD;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { updateReborn } from '../../../keywords/reborn';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const RebornRites: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tfor (const heroPower of input.playerEntity.heroPowers) {\r\n\t\t\tif (heroPower.used) {\r\n\t\t\t\tconst targetEntityId = heroPower.info as number;\r\n\t\t\t\tconst target = input.playerBoard.find((entity) => entity.entityId === targetEntityId);\r\n\t\t\t\tif (!target || target.reborn) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tupdateReborn(\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t);\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n"]}
@@ -4,7 +4,7 @@ exports.Tentacular = void 0;
4
4
  exports.Tentacular = {
5
5
  startOfCombatTiming: 'pre-combat',
6
6
  startOfCombat: (trinket, input) => {
7
- input.playerEntity.heroPowerActivated = false;
7
+ input.playerEntity.heroPowers.find((h) => h.cardId === "BG23_HERO_201p").activated = false;
8
8
  return { hasTriggered: true, shouldRecomputeCurrentAttacker: true };
9
9
  },
10
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"tentacular.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/tentacular.ts"],"names":[],"mappings":";;;AAIa,QAAA,UAAU,GAAsB;IAC5C,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,KAAK,CAAC,YAAY,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAC9C,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const Tentacular: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tinput.playerEntity.heroPowerActivated = false;\r\n\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true };\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"tentacular.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/tentacular.ts"],"names":[],"mappings":";;;AAKa,QAAA,UAAU,GAAsB;IAC5C,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,qBAA8B,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC;QACpG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '@firestone-hs/reference-data';\r\nimport { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const Tentacular: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tinput.playerEntity.heroPowers.find((h) => h.cardId === CardIds.Ozumat_Tentacular).activated = false;\r\n\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true };\r\n\t},\r\n};\r\n"]}
@@ -5,9 +5,11 @@ const deathrattle_effects_1 = require("../../../simulation/deathrattle-effects")
5
5
  exports.WaterInvocation = {
6
6
  startOfCombatTiming: 'pre-combat',
7
7
  startOfCombat: (trinket, input) => {
8
- if (input.playerEntity.heroPowerUsed) {
9
- (0, deathrattle_effects_1.applyWaterInvocationEnchantment)(input.playerBoard, input.playerEntity, null, null, input.playerEntity, input.gameState);
10
- return true;
8
+ for (const heroPower of input.playerEntity.heroPowers) {
9
+ if (heroPower.used) {
10
+ (0, deathrattle_effects_1.applyWaterInvocationEnchantment)(input.playerBoard, input.playerEntity, null, null, input.playerEntity, input.gameState);
11
+ return true;
12
+ }
11
13
  }
12
14
  },
13
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"water-invocation.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/water-invocation.ts"],"names":[],"mappings":";;;AACA,iFAA0F;AAI7E,QAAA,eAAe,GAAsB;IACjD,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,IAAI,KAAK,CAAC,YAAY,CAAC,aAAa,EAAE;YACrC,IAAA,qDAA+B,EAC9B,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,IAAI,EACJ,IAAI,EACJ,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,SAAS,CACf,CAAC;YACF,OAAO,IAAI,CAAC;SACZ;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { applyWaterInvocationEnchantment } from '../../../simulation/deathrattle-effects';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const WaterInvocation: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tif (input.playerEntity.heroPowerUsed) {\r\n\t\t\tapplyWaterInvocationEnchantment(\r\n\t\t\t\tinput.playerBoard,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tnull,\r\n\t\t\t\tnull,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"water-invocation.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/water-invocation.ts"],"names":[],"mappings":";;;AACA,iFAA0F;AAI7E,QAAA,eAAe,GAAsB;IACjD,mBAAmB,EAAE,YAAY;IACjC,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE;YACtD,IAAI,SAAS,CAAC,IAAI,EAAE;gBACnB,IAAA,qDAA+B,EAC9B,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,IAAI,EACJ,IAAI,EACJ,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,OAAO,IAAI,CAAC;aACZ;SACD;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { applyWaterInvocationEnchantment } from '../../../simulation/deathrattle-effects';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const WaterInvocation: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tfor (const heroPower of input.playerEntity.heroPowers) {\r\n\t\t\tif (heroPower.used) {\r\n\t\t\t\tapplyWaterInvocationEnchantment(\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tnull,\r\n\t\t\t\t\tnull,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n"]}
@@ -8,26 +8,28 @@ const utils_2 = require("../../../utils");
8
8
  exports.WaxWarband = {
9
9
  startOfCombatTiming: 'pre-combat',
10
10
  startOfCombat: (trinket, input) => {
11
- if (input.playerEntity.heroPowerUsed) {
12
- if (input.playerBoard.length > 0) {
13
- const boardWithTribes = input.playerBoard.filter((e) => !!(0, utils_2.getEffectiveTribesForEntity)(e, input.playerEntity, input.gameState.allCards).length);
14
- const boardWithoutAll = boardWithTribes.filter((e) => {
15
- var _a;
16
- return !((_a = (0, utils_2.getEffectiveTribesForEntity)(e, input.playerEntity, input.gameState.allCards)) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.Race.ALL));
17
- });
18
- const selectedMinions = selectMinions(boardWithoutAll, reference_data_1.ALL_BG_RACES, input.gameState.allCards);
19
- const allMinions = [
20
- ...selectedMinions,
21
- ...boardWithTribes.filter((e) => {
11
+ for (const heroPower of input.playerEntity.heroPowers) {
12
+ if (heroPower.used) {
13
+ if (input.playerBoard.length > 0) {
14
+ const boardWithTribes = input.playerBoard.filter((e) => !!(0, utils_2.getEffectiveTribesForEntity)(e, input.playerEntity, input.gameState.allCards).length);
15
+ const boardWithoutAll = boardWithTribes.filter((e) => {
22
16
  var _a;
23
- return (_a = (0, utils_2.getEffectiveTribesForEntity)(e, input.playerEntity, input.gameState.allCards)) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.Race.ALL);
24
- }),
25
- ];
26
- allMinions.forEach((e) => {
27
- (0, stats_1.modifyStats)(e, input.gameState.cardsData.getTavernLevel(e.cardId), input.gameState.cardsData.getTavernLevel(e.cardId), input.playerBoard, input.playerEntity, input.gameState);
28
- input.gameState.spectator.registerPowerTarget(input.playerEntity, e, input.playerBoard, input.playerEntity, input.opponentEntity);
29
- });
30
- return true;
17
+ return !((_a = (0, utils_2.getEffectiveTribesForEntity)(e, input.playerEntity, input.gameState.allCards)) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.Race.ALL));
18
+ });
19
+ const selectedMinions = selectMinions(boardWithoutAll, reference_data_1.ALL_BG_RACES, input.gameState.allCards);
20
+ const allMinions = [
21
+ ...selectedMinions,
22
+ ...boardWithTribes.filter((e) => {
23
+ var _a;
24
+ return (_a = (0, utils_2.getEffectiveTribesForEntity)(e, input.playerEntity, input.gameState.allCards)) === null || _a === void 0 ? void 0 : _a.includes(reference_data_1.Race.ALL);
25
+ }),
26
+ ];
27
+ allMinions.forEach((e) => {
28
+ (0, stats_1.modifyStats)(e, input.gameState.cardsData.getTavernLevel(e.cardId), input.gameState.cardsData.getTavernLevel(e.cardId), input.playerBoard, input.playerEntity, input.gameState);
29
+ input.gameState.spectator.registerPowerTarget(input.playerEntity, e, input.playerBoard, input.playerEntity, input.opponentEntity);
30
+ });
31
+ return true;
32
+ }
31
33
  }
32
34
  }
33
35
  },
@@ -1 +1 @@
1
- {"version":3,"file":"wax-warband.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/wax-warband.ts"],"names":[],"mappings":"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","sourcesContent":["import { ALL_BG_RACES, AllCardsService, Race } from '@firestone-hs/reference-data';\r\nimport { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { shuffleArray } from '../../../services/utils';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { getEffectiveTribesForEntity } from '../../../utils';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const WaxWarband: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tif (input.playerEntity.heroPowerUsed) {\r\n\t\t\tif (input.playerBoard.length > 0) {\r\n\t\t\t\tconst boardWithTribes = input.playerBoard.filter(\r\n\t\t\t\t\t(e) => !!getEffectiveTribesForEntity(e, input.playerEntity, input.gameState.allCards).length,\r\n\t\t\t\t);\r\n\t\t\t\tconst boardWithoutAll = boardWithTribes.filter(\r\n\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t!getEffectiveTribesForEntity(e, input.playerEntity, input.gameState.allCards)?.includes(\r\n\t\t\t\t\t\t\tRace.ALL,\r\n\t\t\t\t\t\t),\r\n\t\t\t\t);\r\n\t\t\t\tconst selectedMinions = selectMinions(boardWithoutAll, ALL_BG_RACES, input.gameState.allCards);\r\n\t\t\t\tconst allMinions = [\r\n\t\t\t\t\t...selectedMinions,\r\n\t\t\t\t\t...boardWithTribes.filter((e) =>\r\n\t\t\t\t\t\tgetEffectiveTribesForEntity(e, input.playerEntity, input.gameState.allCards)?.includes(\r\n\t\t\t\t\t\t\tRace.ALL,\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t),\r\n\t\t\t\t];\r\n\t\t\t\tallMinions.forEach((e) => {\r\n\t\t\t\t\tmodifyStats(\r\n\t\t\t\t\t\te,\r\n\t\t\t\t\t\tinput.gameState.cardsData.getTavernLevel(e.cardId),\r\n\t\t\t\t\t\tinput.gameState.cardsData.getTavernLevel(e.cardId),\r\n\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\te,\r\n\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t);\r\n\t\t\t\t});\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n\r\n// Not perfect, as I don't think this solves the issue where some cards are mutually exclusive\r\nconst selectMinions = (minions: BoardEntity[], tribes: Race[], allCards: AllCardsService): BoardEntity[] => {\r\n\t// Step 1\r\n\tconst minionsByTribe: { [tribe: string]: BoardEntity[] } = {};\r\n\tfor (const minion of minions) {\r\n\t\tfor (const tribe of allCards.getCard(minion.cardId).races ?? []) {\r\n\t\t\tif (!minionsByTribe[tribe]) {\r\n\t\t\t\tminionsByTribe[tribe] = [];\r\n\t\t\t}\r\n\t\t\tminionsByTribe[tribe].push(minion);\r\n\t\t}\r\n\t}\r\n\tfor (const tribe of ALL_BG_RACES) {\r\n\t\tminionsByTribe[tribe] = shuffleArray(minionsByTribe[Race[tribe]] ?? []);\r\n\t}\r\n\r\n\tconst selectedMinions: BoardEntity[] = [];\r\n\r\n\t// Step 3\r\n\tfor (const tribe of tribes) {\r\n\t\tif (minionsByTribe[tribe]) {\r\n\t\t\tminionsByTribe[tribe].sort(\r\n\t\t\t\t(a, b) => allCards.getCard(a.cardId).races.length - allCards.getCard(b.cardId).races.length,\r\n\t\t\t);\r\n\t\t\tfor (const minion of minionsByTribe[tribe]) {\r\n\t\t\t\tif (!selectedMinions.includes(minion)) {\r\n\t\t\t\t\tselectedMinions.push(minion);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Step 4\r\n\treturn selectedMinions;\r\n};\r\n"]}
1
+ {"version":3,"file":"wax-warband.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/wax-warband.ts"],"names":[],"mappings":"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","sourcesContent":["import { ALL_BG_RACES, AllCardsService, Race } from '@firestone-hs/reference-data';\r\nimport { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { shuffleArray } from '../../../services/utils';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { getEffectiveTribesForEntity } from '../../../utils';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const WaxWarband: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'pre-combat',\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tfor (const heroPower of input.playerEntity.heroPowers) {\r\n\t\t\tif (heroPower.used) {\r\n\t\t\t\tif (input.playerBoard.length > 0) {\r\n\t\t\t\t\tconst boardWithTribes = input.playerBoard.filter(\r\n\t\t\t\t\t\t(e) => !!getEffectiveTribesForEntity(e, input.playerEntity, input.gameState.allCards).length,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tconst boardWithoutAll = boardWithTribes.filter(\r\n\t\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t\t!getEffectiveTribesForEntity(e, input.playerEntity, input.gameState.allCards)?.includes(\r\n\t\t\t\t\t\t\t\tRace.ALL,\r\n\t\t\t\t\t\t\t),\r\n\t\t\t\t\t);\r\n\t\t\t\t\tconst selectedMinions = selectMinions(boardWithoutAll, ALL_BG_RACES, input.gameState.allCards);\r\n\t\t\t\t\tconst allMinions = [\r\n\t\t\t\t\t\t...selectedMinions,\r\n\t\t\t\t\t\t...boardWithTribes.filter((e) =>\r\n\t\t\t\t\t\t\tgetEffectiveTribesForEntity(e, input.playerEntity, input.gameState.allCards)?.includes(\r\n\t\t\t\t\t\t\t\tRace.ALL,\r\n\t\t\t\t\t\t\t),\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t];\r\n\t\t\t\t\tallMinions.forEach((e) => {\r\n\t\t\t\t\t\tmodifyStats(\r\n\t\t\t\t\t\t\te,\r\n\t\t\t\t\t\t\tinput.gameState.cardsData.getTavernLevel(e.cardId),\r\n\t\t\t\t\t\t\tinput.gameState.cardsData.getTavernLevel(e.cardId),\r\n\t\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\t\te,\r\n\t\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t});\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n\r\n// Not perfect, as I don't think this solves the issue where some cards are mutually exclusive\r\nconst selectMinions = (minions: BoardEntity[], tribes: Race[], allCards: AllCardsService): BoardEntity[] => {\r\n\t// Step 1\r\n\tconst minionsByTribe: { [tribe: string]: BoardEntity[] } = {};\r\n\tfor (const minion of minions) {\r\n\t\tfor (const tribe of allCards.getCard(minion.cardId).races ?? []) {\r\n\t\t\tif (!minionsByTribe[tribe]) {\r\n\t\t\t\tminionsByTribe[tribe] = [];\r\n\t\t\t}\r\n\t\t\tminionsByTribe[tribe].push(minion);\r\n\t\t}\r\n\t}\r\n\tfor (const tribe of ALL_BG_RACES) {\r\n\t\tminionsByTribe[tribe] = shuffleArray(minionsByTribe[Race[tribe]] ?? []);\r\n\t}\r\n\r\n\tconst selectedMinions: BoardEntity[] = [];\r\n\r\n\t// Step 3\r\n\tfor (const tribe of tribes) {\r\n\t\tif (minionsByTribe[tribe]) {\r\n\t\t\tminionsByTribe[tribe].sort(\r\n\t\t\t\t(a, b) => allCards.getCard(a.cardId).races.length - allCards.getCard(b.cardId).races.length,\r\n\t\t\t);\r\n\t\t\tfor (const minion of minionsByTribe[tribe]) {\r\n\t\t\t\tif (!selectedMinions.includes(minion)) {\r\n\t\t\t\t\tselectedMinions.push(minion);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Step 4\r\n\treturn selectedMinions;\r\n};\r\n"]}
@@ -45,7 +45,7 @@ exports.Battlecruiser = {
45
45
  var _a;
46
46
  const advancedBallistics = (_a = minion.enchantments) === null || _a === void 0 ? void 0 : _a.find((e) => e.cardId === "BG31_HERO_801ptde");
47
47
  if (!advancedBallistics) {
48
- return;
48
+ return { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };
49
49
  }
50
50
  const buff = advancedBallistics.tagScriptDataNum1;
51
51
  const targets = input.attackingBoard.filter((entity) => entity !== minion);
@@ -1 +1 @@
1
- {"version":3,"file":"battlecruiser.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/battlecruiser.ts"],"names":[],"mappings":";;;AAEA,uDAAgE;AAKhE,qDAAwD;AACxD,0CAAkE;AAGrD,QAAA,aAAa,GAAgF;IACzG,OAAO,EAAE,wCAA6F;IACtG,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;;QACvD,MAAM,YAAY,GAAG,MAAA,MAAM,CAAC,YAAY,0CAAE,IAAI,CAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,wBAAmE,CAClF,CAAC;QACF,IAAI,CAAC,YAAY,EAAE;YAClB,OAAO,KAAK,CAAC;SACb;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,iBAAiB,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAA,wCAAgC,EAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACrE,IAAI,CAAC,CAAC,MAAM,EAAE;YACb,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,uBAAsD,CACrE;gBACA,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,CAAC,CAAC;YACL,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC/B,IAAA,2BAAkB,EACjB,MAAM,EACN,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,MAAM,EACN,MAAM,EACN,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,MAAM,EACN,MAAM,EACN,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;aACF;SACD;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,YAAY,EAAE,CAAC,MAAmB,EAAE,KAAwB,EAAE,EAAE;;QAC/D,MAAM,cAAc,GAAG,MAAA,MAAM,CAAC,YAAY,0CAAE,IAAI,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,wBAAuE,CACtF,CAAC;QACF,IAAI,CAAC,cAAc,EAAE;YACpB,OAAO;SACP;QAED,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC,YAAY,CAAC;QACvD,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC;QAC9C,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC;QACjD,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC;QAC9C,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC;QACjD,MAAM,CAAC,YAAY,GAAG,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC;QAC1D,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC;QACzC,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC;QAC/C,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC;IAClD,CAAC;IACD,QAAQ,EAAE,CACT,MAAmB,EACnB,KAAoB,EAInB,EAAE;;QACH,MAAM,kBAAkB,GAAG,MAAA,MAAM,CAAC,YAAY,0CAAE,IAAI,CACnD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,wBAA+E,CAC9F,CAAC;QACF,IAAI,CAAC,kBAAkB,EAAE;YACxB,OAAO;SACP;QAED,MAAM,IAAI,GAAG,kBAAkB,CAAC,iBAAiB,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAC3E,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC7B,IAAA,mBAAW,EAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;SACzF;QACD,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IACD,iBAAiB,EAAE,CAAC,MAAmB,EAAE,KAAgC,EAAE,EAAE;;QAC5E,MAAM,eAAe,GAAG,MAAA,MAAM,CAAC,YAAY,0CAAE,IAAI,CAChD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,wBAAyE,CACxF,CAAC;QACF,IAAI,CAAC,eAAe,EAAE;YACrB,OAAO;SACP;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,EAAE;YACZ,OAAO;SACP;QAED,MAAM,IAAI,GAAG,eAAe,CAAC,iBAAiB,CAAC;QAC/C,IAAA,mBAAW,EAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC5G,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { dealDamageToMinion } from '../../../simulation/attack';\r\nimport { DeathrattleTriggeredInput } from '../../../simulation/deathrattle-on-trigger';\r\nimport { OnAttackInput } from '../../../simulation/on-attack';\r\nimport { RebornEffectInput } from '../../../simulation/reborn';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { getRandomMinionWithHighestHealth } from '../../../utils';\r\nimport { DeathrattleEffectCard, OnAttackCard, RebornEffectCard, StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const Battlecruiser: StartOfCombatCard & RebornEffectCard & OnAttackCard & DeathrattleEffectCard = {\r\n\tcardIds: [CardIds.LiftOff_BattlecruiserToken_BG31_HERO_801pt, CardIds.Battlecruiser_BG31_HERO_801pt_G],\r\n\tstartOfCombat: (minion: BoardEntity, input: SoCInput) => {\r\n\t\tconst yamatoCannon = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.YamatoCannon_YamatoCannonEnchantment_BG31_HERO_801ptce,\r\n\t\t);\r\n\t\tif (!yamatoCannon) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst damage = yamatoCannon.tagScriptDataNum1;\r\n\t\tconst target = getRandomMinionWithHighestHealth(input.opponentBoard);\r\n\t\tif (!!target) {\r\n\t\t\tconst loops = !!minion.enchantments.find(\r\n\t\t\t\t(e) => e.cardId === CardIds.Battlecruiser_MissilePod_BG31_HERO_801pti,\r\n\t\t\t)\r\n\t\t\t\t? 2\r\n\t\t\t\t: 1;\r\n\t\t\tfor (let i = 0; i < loops; i++) {\r\n\t\t\t\tdealDamageToMinion(\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\tminion,\r\n\t\t\t\t\tdamage,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tminion,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn true;\r\n\t},\r\n\trebornEffect: (minion: BoardEntity, input: RebornEffectInput) => {\r\n\t\tconst ultraCapacitor = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.UltraCapacitor_UltraCapacitorEnchantment_BG31_HERO_801ptje,\r\n\t\t);\r\n\t\tif (!ultraCapacitor) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tminion.enchantments = input.initialEntity.enchantments;\r\n\t\tminion.attack = input.initialEntity.maxAttack;\r\n\t\tminion.maxAttack = input.initialEntity.maxAttack;\r\n\t\tminion.health = input.initialEntity.maxHealth;\r\n\t\tminion.maxHealth = input.initialEntity.maxHealth;\r\n\t\tminion.divineShield = input.initialEntity.hadDivineShield;\r\n\t\tminion.taunt = input.initialEntity.taunt;\r\n\t\tminion.windfury = input.initialEntity.windfury;\r\n\t\tminion.poisonous = input.initialEntity.poisonous;\r\n\t},\r\n\tonAttack: (\r\n\t\tminion: BoardEntity,\r\n\t\tinput: OnAttackInput,\r\n\t): {\r\n\t\tdmgDoneByAttacker: number;\r\n\t\tdmgDoneByDefender: number;\r\n\t} => {\r\n\t\tconst advancedBallistics = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.AdvancedBallistics_AdvancedBallisticsEnchantment_BG31_HERO_801ptde,\r\n\t\t);\r\n\t\tif (!advancedBallistics) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst buff = advancedBallistics.tagScriptDataNum1;\r\n\t\tconst targets = input.attackingBoard.filter((entity) => entity !== minion);\r\n\t\tfor (const target of targets) {\r\n\t\t\tmodifyStats(target, buff, 0, input.attackingBoard, input.attackingHero, input.gameState);\r\n\t\t}\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n\tdeathrattleEffect: (minion: BoardEntity, input: DeathrattleTriggeredInput) => {\r\n\t\tconst caduceusReactor = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\r\n\t\t);\r\n\t\tif (!caduceusReactor) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst target = input.boardWithDeadEntity[0];\r\n\t\tif (!target) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst buff = caduceusReactor.tagScriptDataNum1;\r\n\t\tmodifyStats(target, buff, buff, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.gameState);\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"battlecruiser.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/battlecruiser.ts"],"names":[],"mappings":"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","sourcesContent":["import { CardIds } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { dealDamageToMinion } from '../../../simulation/attack';\r\nimport { DeathrattleTriggeredInput } from '../../../simulation/deathrattle-on-trigger';\r\nimport { OnAttackInput } from '../../../simulation/on-attack';\r\nimport { RebornEffectInput } from '../../../simulation/reborn';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { getRandomMinionWithHighestHealth } from '../../../utils';\r\nimport { DeathrattleEffectCard, OnAttackCard, RebornEffectCard, StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const Battlecruiser: StartOfCombatCard & RebornEffectCard & OnAttackCard & DeathrattleEffectCard = {\r\n\tcardIds: [CardIds.LiftOff_BattlecruiserToken_BG31_HERO_801pt, CardIds.Battlecruiser_BG31_HERO_801pt_G],\r\n\tstartOfCombat: (minion: BoardEntity, input: SoCInput) => {\r\n\t\tconst yamatoCannon = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.YamatoCannon_YamatoCannonEnchantment_BG31_HERO_801ptce,\r\n\t\t);\r\n\t\tif (!yamatoCannon) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst damage = yamatoCannon.tagScriptDataNum1;\r\n\t\tconst target = getRandomMinionWithHighestHealth(input.opponentBoard);\r\n\t\tif (!!target) {\r\n\t\t\tconst loops = !!minion.enchantments.find(\r\n\t\t\t\t(e) => e.cardId === CardIds.Battlecruiser_MissilePod_BG31_HERO_801pti,\r\n\t\t\t)\r\n\t\t\t\t? 2\r\n\t\t\t\t: 1;\r\n\t\t\tfor (let i = 0; i < loops; i++) {\r\n\t\t\t\tdealDamageToMinion(\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\tminion,\r\n\t\t\t\t\tdamage,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tminion,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn true;\r\n\t},\r\n\trebornEffect: (minion: BoardEntity, input: RebornEffectInput) => {\r\n\t\tconst ultraCapacitor = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.UltraCapacitor_UltraCapacitorEnchantment_BG31_HERO_801ptje,\r\n\t\t);\r\n\t\tif (!ultraCapacitor) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tminion.enchantments = input.initialEntity.enchantments;\r\n\t\tminion.attack = input.initialEntity.maxAttack;\r\n\t\tminion.maxAttack = input.initialEntity.maxAttack;\r\n\t\tminion.health = input.initialEntity.maxHealth;\r\n\t\tminion.maxHealth = input.initialEntity.maxHealth;\r\n\t\tminion.divineShield = input.initialEntity.hadDivineShield;\r\n\t\tminion.taunt = input.initialEntity.taunt;\r\n\t\tminion.windfury = input.initialEntity.windfury;\r\n\t\tminion.poisonous = input.initialEntity.poisonous;\r\n\t},\r\n\tonAttack: (\r\n\t\tminion: BoardEntity,\r\n\t\tinput: OnAttackInput,\r\n\t): {\r\n\t\tdmgDoneByAttacker: number;\r\n\t\tdmgDoneByDefender: number;\r\n\t} => {\r\n\t\tconst advancedBallistics = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.AdvancedBallistics_AdvancedBallisticsEnchantment_BG31_HERO_801ptde,\r\n\t\t);\r\n\t\tif (!advancedBallistics) {\r\n\t\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t\t}\r\n\r\n\t\tconst buff = advancedBallistics.tagScriptDataNum1;\r\n\t\tconst targets = input.attackingBoard.filter((entity) => entity !== minion);\r\n\t\tfor (const target of targets) {\r\n\t\t\tmodifyStats(target, buff, 0, input.attackingBoard, input.attackingHero, input.gameState);\r\n\t\t}\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n\tdeathrattleEffect: (minion: BoardEntity, input: DeathrattleTriggeredInput) => {\r\n\t\tconst caduceusReactor = minion.enchantments?.find(\r\n\t\t\t(e) => e.cardId === CardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\r\n\t\t);\r\n\t\tif (!caduceusReactor) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst target = input.boardWithDeadEntity[0];\r\n\t\tif (!target) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst buff = caduceusReactor.tagScriptDataNum1;\r\n\t\tmodifyStats(target, buff, buff, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.gameState);\r\n\t},\r\n};\r\n"]}
@@ -141,7 +141,7 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
141
141
  updateSimulationResult(simulationResult, inputReady);
142
142
  !((_k = battleInput.options) === null || _k === void 0 ? void 0 : _k.skipInfoLogs) && console.timeEnd('simulation');
143
143
  spectator.prune();
144
- simulationResult.outcomeSamples = spectator.buildOutcomeSamples();
144
+ simulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);
145
145
  return simulationResult;
146
146
  };
147
147
  exports.simulateBattle = simulateBattle;
@@ -1 +1 @@
1
- {"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":";;;AACA,iEAAwE;AAExE,2DAAyG;AACzG,mDAA+C;AAC/C,gEAA2D;AAC3D,+CAA4C;AAC5C,yDAAqD;AAGrD,4DAAwD;AACxD,sDAAmD;AACnD,gEAA6D;AAE7D,IAAI,WAAW,GAAG,IAAI,gCAAe,EAAE,CAAC;AAEjC,MAAM,WAAW,GAAG,CAAC,KAAsB,EAAE,EAAE;IACrD,WAAW,GAAG,KAAK,CAAC;AACrB,CAAC,CAAC;AAFW,QAAA,WAAW,eAEtB;AAKF,kBAAe,KAAK,EAAE,KAAK,EAAgB,EAAE;;IAC5C,IAAI,CAAC,CAAA,MAAA,KAAK,CAAC,IAAI,0CAAE,MAAM,CAAA,EAAE;QACxB,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO;KACP;IAED,MAAM,WAAW,GAAkB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,WAAW,CAAC;IAC1B,MAAM,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9C,SAAS,CAAC,YAAY,CACrB,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,WAAW,mCAAI,MAAA,WAAW,CAAC,OAAO,0CAAE,WAAW,EACtE,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,SAAS,mCAAI,EAAE,CACtC,CAAC;IACF,MAAM,cAAc,GAAG,IAAA,sBAAc,EAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAGrE,IAAI,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;QACpB,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC;KAC/B;IAED,MAAM,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC;IAGtC,MAAM,QAAQ,GAAG;QAChB,UAAU,EAAE,GAAG;QACf,eAAe,EAAE,KAAK;QACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;KACtC,CAAC;IACF,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEK,MAAM,cAAc,GAAG,QAAQ,CAAC,EACtC,WAA0B,EAC1B,KAAsB,EACtB,SAAoB;;IAEpB,IAAI,CAAC,CAAA,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,QAAQ,EAAE,0CAAE,MAAM,CAAA,EAAE;QAC/B,OAAO,CAAC,KAAK,CAAC,yEAAyE,EAAE,KAAK,CAAC,CAAC;QAChG,OAAO,IAAI,CAAC;KACZ;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,qBAAqB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,qBAAqB,KAAI,IAAI,CAAC;IACjF,MAAM,mBAAmB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,mBAAmB,KAAI,IAAI,CAAC;IAC7E,MAAM,iBAAiB,GAAG,MAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,mBAAmB,mCAAI,GAAG,CAAC;IAC1E,MAAM,qBAAqB,GAAG,MAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,qBAAqB,mCAAI,IAAI,CAAC;IACjF,MAAM,gBAAgB,GAAqB;QAC1C,SAAS,EAAE,CAAC;QACZ,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,IAAI,EAAE,CAAC;QACP,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,gBAAgB,EAAE,SAAS;QAC3B,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,SAAS;QACtB,iBAAiB,EAAE,SAAS;QAC5B,gBAAgB,EAAE,SAAS;QAC3B,iBAAiB,EAAE,SAAS;KAC5B,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,qBAAqB,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAA,kCAAe,EAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAkB,IAAA,yBAAW,EAAC,UAAU,CAAC,CAAC;QACrD,MAAM,UAAU,GAAkB,IAAA,yBAAW,EAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAkB;YAChC,QAAQ,EAAE,KAAK;YACf,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,SAAS;YACpB,WAAW,EAAE,IAAI,0BAAW,EAAE;YAC9B,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW;YACxC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW;YACxC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS;YACpC,SAAS,EAAE;gBACV,MAAM,EAAE;oBACP,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,MAAM;oBAChC,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,KAAK;oBAC9B,QAAQ,EAAE,KAAK,CAAC,mBAAmB;iBACnC;gBACD,QAAQ,EAAE;oBACT,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,MAAM;oBAClC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK;oBAChC,QAAQ,EAAE,KAAK,CAAC,qBAAqB;iBACrC;gBACD,aAAa,EAAE;oBACd,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,MAAM;oBACrC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK;oBACnC,QAAQ,EAAE,UAAU,CAAC,mBAAmB;iBACxC;gBACD,eAAe,EAAE;oBAChB,MAAM,EAAE,UAAU,CAAC,aAAa,CAAC,MAAM;oBACvC,KAAK,EAAE,UAAU,CAAC,aAAa,CAAC,KAAK;oBACrC,QAAQ,EAAE,UAAU,CAAC,qBAAqB;iBAC1C;aACD;SACD,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,SAAS,CAAC,oBAAoB,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC9G,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,qBAAqB,EAAE;YAE/C,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC;YAC1F,MAAM;SACN;QACD,IAAI,CAAC,YAAY,EAAE;YAClB,SAAS;SACT;QACD,IAAI,YAAY,CAAC,MAAM,KAAK,KAAK,EAAE;YAClC,gBAAgB,CAAC,GAAG,EAAE,CAAC;YACvB,gBAAgB,CAAC,SAAS,IAAI,YAAY,CAAC,WAAW,CAAC;YACvD,IAAI,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE;gBACxE,gBAAgB,CAAC,SAAS,EAAE,CAAC;aAC7B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;YACxB,gBAAgB,CAAC,UAAU,IAAI,YAAY,CAAC,WAAW,CAAC;YACxD,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAA,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnF,IACC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;gBACrC,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAChE;gBACD,gBAAgB,CAAC,UAAU,EAAE,CAAC;aAC9B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;SACxB;QACD,SAAS,CAAC,kBAAkB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAGlD,IAAI,CAAC,CAAC,iBAAiB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,iBAAiB,KAAK,CAAC,EAAE;YAChE,sBAAsB,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;YACrD,MAAM,gBAAgB,CAAC;SACvB;KACD;IACD,sBAAsB,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;IACrD,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpE,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,gBAAgB,CAAC,cAAc,GAAG,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAElE,OAAO,gBAAgB,CAAC;AACzB,CAAC,CAAC;AAjHW,QAAA,cAAc,kBAiHzB;AAEF,MAAM,sBAAsB,GAAG,CAAC,gBAAkC,EAAE,KAAoB,EAAE,EAAE;IAC3F,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;IAC1F,gBAAgB,CAAC,UAAU,GAAG,aAAa,CAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACnE,gBAAgB,CAAC,GAAG,EACpB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,gBAAgB,GAAG,aAAa,CAChD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACzE,gBAAgB,CAAC,SAAS,EAC1B,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACpE,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,iBAAiB,GAAG,aAAa,CACjD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EAC1E,gBAAgB,CAAC,UAAU,EAC3B,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,gBAAgB,CAAC,WAAW,GAAG,gBAAgB,CAAC,UAAU,CAAC,EAC7E,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IAIF,gBAAgB,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjH,gBAAgB,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,IAAI;QACzD,CAAC,CAAC,gBAAgB,CAAC,UAAU,GAAG,gBAAgB,CAAC,IAAI;QACrD,CAAC,CAAC,CAAC,CAAC;IACL,IACC,gBAAgB,CAAC,gBAAgB,GAAG,CAAC;QACrC,gBAAgB,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,EACtE;QACD,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;KACzC;IACD,IACC,gBAAgB,CAAC,iBAAiB,GAAG,CAAC;QACtC,gBAAgB,CAAC,iBAAiB,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,EACzE;QACD,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;KAC1C;AACF,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,YAAoB,EAAE,YAAoB,EAAE,UAAkB,EAAU,EAAE;IAChG,IAAI,YAAY,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC,EAAE;QAC7C,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,YAAY,KAAK,GAAG,IAAI,YAAY,KAAK,UAAU,EAAE;QACxD,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AAGF,MAAM,8BAA8B,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBtC,CAAC;AACF,MAAM,uCAAuC,GAAG,EAAE,CAAC;AAC5C,MAAM,6BAA6B,GAAG,CAAC,MAAc,EAAW,EAAE;IACxE,IAAI,8BAA8B,CAAC,QAAQ,CAAC,MAAiB,CAAC,EAAE;QAC/D,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,uCAAuC,CAAC,MAAM,KAAK,CAAC,EAAE;QACzD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,6BAAY,CAAC,EAAE;YACnD,IAAI,IAAA,gDAA+B,EAAC,QAAQ,CAAC,IAAI,IAAA,+CAA8B,EAAC,QAAQ,CAAC,EAAE;gBAC1F,uCAAuC,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;aAClE;SACD;KACD;IACD,OAAO,uCAAuC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC,CAAC;AAZW,QAAA,6BAA6B,iCAYxC","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, CardIds } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { hasDeathrattleEnchantmentEffect, hasDeathrattleSpawnEnchantment } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { cloneInput3 } from './input-clone';\r\nimport { buildFinalInput } from './input-sanitation';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { FullGameState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\n\r\nlet globalCards = new AllCardsService();\r\n\r\nexport const assignCards = (cards: AllCardsService) => {\r\n\tglobalCards = cards;\r\n};\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tif (!event.body?.length) {\r\n\t\tconsole.warn('missing event body', event);\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tconst cards = globalCards;\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\t// Iterate through all intermediate results to reach the final result\r\n\tlet result = battleIterator.next();\r\n\twhile (!result.done) {\r\n\t\tresult = battleIterator.next();\r\n\t}\r\n\r\n\tconst simulationResult = result.value;\r\n\t// console.debug('simulationResult', simulationResult);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = function* (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): Generator<SimulationResult, SimulationResult, void> {\r\n\tif (!cards?.getCards()?.length) {\r\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\r\n\t\treturn null;\r\n\t}\r\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\r\n\tconst start = Date.now();\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\r\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\r\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWon: 0,\r\n\t\tdamageLost: 0,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst spectator = new Spectator(includeOutcomeSamples);\r\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst gameState: FullGameState = {\r\n\t\t\tallCards: cards,\r\n\t\t\tcardsData: cardsData,\r\n\t\t\tspectator: spectator,\r\n\t\t\tsharedState: new SharedState(),\r\n\t\t\tcurrentTurn: input.gameState.currentTurn,\r\n\t\t\tvalidTribes: input.gameState.validTribes,\r\n\t\t\tanomalies: input.gameState.anomalies,\r\n\t\t\tgameState: {\r\n\t\t\t\tplayer: {\r\n\t\t\t\t\tplayer: input.playerBoard.player,\r\n\t\t\t\t\tboard: input.playerBoard.board,\r\n\t\t\t\t\tteammate: input.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponent: {\r\n\t\t\t\t\tplayer: input.opponentBoard.player,\r\n\t\t\t\t\tboard: input.opponentBoard.board,\r\n\t\t\t\t\tteammate: input.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\tplayerInitial: {\r\n\t\t\t\t\tplayer: inputClone.playerBoard.player,\r\n\t\t\t\t\tboard: inputClone.playerBoard.board,\r\n\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponentInitial: {\r\n\t\t\t\t\tplayer: inputClone.opponentBoard.player,\r\n\t\t\t\t\tboard: inputClone.opponentBoard.board,\r\n\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t\tconst simulator = new Simulator(gameState);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);\r\n\t\tif (Date.now() - start > maxAcceptableDuration) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\r\n\t\t// Yield intermediate result every 200 iterations\r\n\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\r\n\t\t\tupdateSimulationResult(simulationResult, inputReady);\r\n\t\t\tyield simulationResult;\r\n\t\t}\r\n\t}\r\n\tupdateSimulationResult(simulationResult, inputReady);\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples();\r\n\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\r\n\treturn simulationResult;\r\n};\r\n\r\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo) => {\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? simulationResult.damageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost\r\n\t\t? simulationResult.damageLost / simulationResult.lost\r\n\t\t: 0;\r\n\tif (\r\n\t\tsimulationResult.averageDamageWon > 0 &&\r\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage won issue');\r\n\t}\r\n\tif (\r\n\t\tsimulationResult.averageDamageLost > 0 &&\r\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage lost issue');\r\n\t}\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\n// Used when triggering random deathrattles\r\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\r\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\r\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\r\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\r\n];\r\nconst validDeathrattleEnchantmentsFromMapping = [];\r\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\r\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\r\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\r\n\t\t\tif (hasDeathrattleEnchantmentEffect(cardImpl) || hasDeathrattleSpawnEnchantment(cardImpl)) {\r\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\r\n};\r\n\r\n// const cleanEnchantmentsForEntity = (\r\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n// \tentityIds: readonly number[],\r\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n// \treturn enchantments.filter(\r\n// \t\t(enchant) =>\r\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n// \t);\r\n// };\r\n"]}
1
+ {"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, CardIds } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { hasDeathrattleEnchantmentEffect, hasDeathrattleSpawnEnchantment } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { cloneInput3 } from './input-clone';\r\nimport { buildFinalInput } from './input-sanitation';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { FullGameState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\n\r\nlet globalCards = new AllCardsService();\r\n\r\nexport const assignCards = (cards: AllCardsService) => {\r\n\tglobalCards = cards;\r\n};\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tif (!event.body?.length) {\r\n\t\tconsole.warn('missing event body', event);\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tconst cards = globalCards;\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\t// Iterate through all intermediate results to reach the final result\r\n\tlet result = battleIterator.next();\r\n\twhile (!result.done) {\r\n\t\tresult = battleIterator.next();\r\n\t}\r\n\r\n\tconst simulationResult = result.value;\r\n\t// console.debug('simulationResult', simulationResult);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = function* (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): Generator<SimulationResult, SimulationResult, void> {\r\n\tif (!cards?.getCards()?.length) {\r\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\r\n\t\treturn null;\r\n\t}\r\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\r\n\tconst start = Date.now();\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\r\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\r\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWon: 0,\r\n\t\tdamageLost: 0,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst spectator = new Spectator(includeOutcomeSamples);\r\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst gameState: FullGameState = {\r\n\t\t\tallCards: cards,\r\n\t\t\tcardsData: cardsData,\r\n\t\t\tspectator: spectator,\r\n\t\t\tsharedState: new SharedState(),\r\n\t\t\tcurrentTurn: input.gameState.currentTurn,\r\n\t\t\tvalidTribes: input.gameState.validTribes,\r\n\t\t\tanomalies: input.gameState.anomalies,\r\n\t\t\tgameState: {\r\n\t\t\t\tplayer: {\r\n\t\t\t\t\tplayer: input.playerBoard.player,\r\n\t\t\t\t\tboard: input.playerBoard.board,\r\n\t\t\t\t\tteammate: input.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponent: {\r\n\t\t\t\t\tplayer: input.opponentBoard.player,\r\n\t\t\t\t\tboard: input.opponentBoard.board,\r\n\t\t\t\t\tteammate: input.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\tplayerInitial: {\r\n\t\t\t\t\tplayer: inputClone.playerBoard.player,\r\n\t\t\t\t\tboard: inputClone.playerBoard.board,\r\n\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponentInitial: {\r\n\t\t\t\t\tplayer: inputClone.opponentBoard.player,\r\n\t\t\t\t\tboard: inputClone.opponentBoard.board,\r\n\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t\tconst simulator = new Simulator(gameState);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);\r\n\t\tif (Date.now() - start > maxAcceptableDuration) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\r\n\t\t// Yield intermediate result every 200 iterations\r\n\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\r\n\t\t\tupdateSimulationResult(simulationResult, inputReady);\r\n\t\t\tyield simulationResult;\r\n\t\t}\r\n\t}\r\n\tupdateSimulationResult(simulationResult, inputReady);\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);\r\n\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\r\n\treturn simulationResult;\r\n};\r\n\r\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo) => {\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? simulationResult.damageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost\r\n\t\t? simulationResult.damageLost / simulationResult.lost\r\n\t\t: 0;\r\n\tif (\r\n\t\tsimulationResult.averageDamageWon > 0 &&\r\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage won issue');\r\n\t}\r\n\tif (\r\n\t\tsimulationResult.averageDamageLost > 0 &&\r\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage lost issue');\r\n\t}\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\n// Used when triggering random deathrattles\r\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\r\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\r\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\r\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\r\n];\r\nconst validDeathrattleEnchantmentsFromMapping = [];\r\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\r\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\r\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\r\n\t\t\tif (hasDeathrattleEnchantmentEffect(cardImpl) || hasDeathrattleSpawnEnchantment(cardImpl)) {\r\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\r\n};\r\n\r\n// const cleanEnchantmentsForEntity = (\r\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n// \tentityIds: readonly number[],\r\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n// \treturn enchantments.filter(\r\n// \t\t(enchant) =>\r\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n// \t);\r\n// };\r\n"]}
@@ -1,4 +1,5 @@
1
1
  import { GameAction } from './game-action';
2
2
  export interface GameSample {
3
3
  readonly actions: readonly GameAction[];
4
+ readonly anomalies: readonly string[];
4
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"game-sample.js","sourceRoot":"","sources":["../../../src/simulation/spectator/game-sample.ts"],"names":[],"mappings":"","sourcesContent":["import { GameAction } from './game-action';\r\n\r\nexport interface GameSample {\r\n\treadonly actions: readonly GameAction[];\r\n\t/*\r\n\treadonly playerCardId: string;\r\n\treadonly playerEntityId: number;\r\n\treadonly playerHeroPowerCardId: string;\r\n\treadonly playerHeroPowerUsed: boolean;\r\n\treadonly opponentCardId: string;\r\n\treadonly opponentEntityId: number;\r\n\treadonly opponentHeroPowerCardId: string;\r\n\treadonly opponentHeroPowerUsed: boolean;\r\n\t*/\r\n}\r\n"]}
1
+ {"version":3,"file":"game-sample.js","sourceRoot":"","sources":["../../../src/simulation/spectator/game-sample.ts"],"names":[],"mappings":"","sourcesContent":["import { GameAction } from './game-action';\r\n\r\nexport interface GameSample {\r\n\treadonly actions: readonly GameAction[];\r\n\treadonly anomalies: readonly string[];\r\n\t/*\r\n\treadonly playerCardId: string;\r\n\treadonly playerEntityId: number;\r\n\treadonly playerHeroPowerCardId: string;\r\n\treadonly playerHeroPowerUsed: boolean;\r\n\treadonly opponentCardId: string;\r\n\treadonly opponentEntityId: number;\r\n\treadonly opponentHeroPowerCardId: string;\r\n\treadonly opponentHeroPowerUsed: boolean;\r\n\t*/\r\n}\r\n"]}
@@ -1,3 +1,4 @@
1
+ import { BgsGameState } from '../../bgs-battle-info';
1
2
  import { BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';
2
3
  import { BoardEntity } from '../../board-entity';
3
4
  import { BoardSecret } from '../../board-secret';
@@ -10,7 +11,7 @@ export declare class Spectator {
10
11
  private lostBattles;
11
12
  constructor(enabled: boolean);
12
13
  prune(): void;
13
- buildOutcomeSamples(): {
14
+ buildOutcomeSamples(gameState: BgsGameState): {
14
15
  won: readonly GameSample[];
15
16
  lost: readonly GameSample[];
16
17
  tied: readonly GameSample[];
@@ -16,7 +16,7 @@ class Spectator {
16
16
  this.lostBattles = this.lostBattles.slice(0, MAX_SAMPLES);
17
17
  this.tiedBattles = this.tiedBattles.slice(0, MAX_SAMPLES);
18
18
  }
19
- buildOutcomeSamples() {
19
+ buildOutcomeSamples(gameState) {
20
20
  var _a, _b, _c;
21
21
  if (!this.enabled) {
22
22
  return {
@@ -26,16 +26,17 @@ class Spectator {
26
26
  };
27
27
  }
28
28
  return {
29
- won: (_a = this.wonBattles) === null || _a === void 0 ? void 0 : _a.map((battle) => this.cleanUpActions(battle)),
30
- lost: (_b = this.lostBattles) === null || _b === void 0 ? void 0 : _b.map((battle) => this.cleanUpActions(battle)),
31
- tied: (_c = this.tiedBattles) === null || _c === void 0 ? void 0 : _c.map((battle) => this.cleanUpActions(battle)),
29
+ won: (_a = this.wonBattles) === null || _a === void 0 ? void 0 : _a.map((battle) => this.cleanUpActions(battle, gameState)),
30
+ lost: (_b = this.lostBattles) === null || _b === void 0 ? void 0 : _b.map((battle) => this.cleanUpActions(battle, gameState)),
31
+ tied: (_c = this.tiedBattles) === null || _c === void 0 ? void 0 : _c.map((battle) => this.cleanUpActions(battle, gameState)),
32
32
  };
33
33
  }
34
- cleanUpActions(battle) {
34
+ cleanUpActions(battle, gameState) {
35
35
  const collapsed = this.collapseActions(battle.actions);
36
36
  const result = {
37
37
  ...battle,
38
38
  actions: collapsed,
39
+ anomalies: gameState.anomalies,
39
40
  };
40
41
  return result;
41
42
  }
@@ -54,6 +55,7 @@ class Spectator {
54
55
  this.actionsForCurrentBattle = [];
55
56
  const battle = {
56
57
  actions: actionsForBattle,
58
+ anomalies: [],
57
59
  };
58
60
  switch (result) {
59
61
  case 'won':