@firestone-hs/simulate-bgs-battle 1.1.730 → 1.1.732

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/bgs-battle-options.d.ts +1 -0
  2. package/dist/bgs-battle-options.js.map +1 -1
  3. package/dist/bgs-player-entity.d.ts +1 -0
  4. package/dist/bgs-player-entity.js.map +1 -1
  5. package/dist/cards/impl/_card-mappings.js +82 -74
  6. package/dist/cards/impl/_card-mappings.js.map +1 -1
  7. package/dist/cards/impl/bg-spell/sharing-is-caring.js.map +1 -1
  8. package/dist/cards/impl/bg-spell/toxic-tumbleweed.js.map +1 -1
  9. package/dist/cards/impl/hero-power/aim-high.js.map +1 -1
  10. package/dist/cards/impl/hero-power/aim-left.js.map +1 -1
  11. package/dist/cards/impl/hero-power/aim-low.js.map +1 -1
  12. package/dist/cards/impl/hero-power/aim-right.js.map +1 -1
  13. package/dist/cards/impl/hero-power/avatar-of-nzoth.d.ts +2 -0
  14. package/dist/cards/impl/hero-power/avatar-of-nzoth.js +22 -0
  15. package/dist/cards/impl/hero-power/avatar-of-nzoth.js.map +1 -0
  16. package/dist/cards/impl/hero-power/earth-invocation.js.map +1 -1
  17. package/dist/cards/impl/hero-power/embrace-your-rage.js.map +1 -1
  18. package/dist/cards/impl/hero-power/fire-invocation.js.map +1 -1
  19. package/dist/cards/impl/hero-power/reborn-rites.js.map +1 -1
  20. package/dist/cards/impl/hero-power/water-invocation.js.map +1 -1
  21. package/dist/cards/impl/minion/all-seeing-elder.js.map +1 -1
  22. package/dist/cards/impl/minion/alleycat.js.map +1 -1
  23. package/dist/cards/impl/minion/amber-guardian.js.map +1 -1
  24. package/dist/cards/impl/minion/archimonde.js.map +1 -1
  25. package/dist/cards/impl/minion/arid-atrocity.js.map +1 -1
  26. package/dist/cards/impl/minion/ashen-corruptor.js.map +1 -1
  27. package/dist/cards/impl/minion/assistant-guard.js.map +1 -1
  28. package/dist/cards/impl/minion/audacious-anchor.js.map +1 -1
  29. package/dist/cards/impl/minion/auto-assembler-enchantment.js +1 -6
  30. package/dist/cards/impl/minion/auto-assembler-enchantment.js.map +1 -1
  31. package/dist/cards/impl/minion/auto-assembler.js.map +1 -1
  32. package/dist/cards/impl/minion/avalanche-caller.js.map +1 -1
  33. package/dist/cards/impl/minion/baneling.js.map +1 -1
  34. package/dist/cards/impl/minion/bigwig-bandit.js.map +1 -1
  35. package/dist/cards/impl/minion/bird-buddy.js.map +1 -1
  36. package/dist/cards/impl/minion/blazing-skyfin.js.map +1 -1
  37. package/dist/cards/impl/minion/blue-whelp.js.map +1 -1
  38. package/dist/cards/impl/minion/boar-gamer.js.map +1 -1
  39. package/dist/cards/impl/minion/briarback-bookie.js.map +1 -1
  40. package/dist/cards/impl/minion/bronze-steward.js.map +1 -1
  41. package/dist/cards/impl/minion/bubble-gunner.js.map +1 -1
  42. package/dist/cards/impl/minion/buzzing-vermin.js.map +1 -1
  43. package/dist/cards/impl/minion/cadaver-caretaker.js.map +1 -1
  44. package/dist/cards/impl/minion/captain-bonerender.js.map +1 -1
  45. package/dist/cards/impl/minion/carapace-raiser.js.map +1 -1
  46. package/dist/cards/impl/minion/carbonic-copy.js.map +1 -1
  47. package/dist/cards/impl/minion/choral-mrrrglr.js +1 -1
  48. package/dist/cards/impl/minion/choral-mrrrglr.js.map +1 -1
  49. package/dist/cards/impl/minion/coilskar-sapper.js.map +1 -1
  50. package/dist/cards/impl/minion/coldlight-diver.js.map +1 -1
  51. package/dist/cards/impl/minion/crystal-infuser-enchantment.js.map +1 -1
  52. package/dist/cards/impl/minion/cupcake-peddler.js.map +1 -1
  53. package/dist/cards/impl/minion/deadstomper.js.map +1 -1
  54. package/dist/cards/impl/minion/deathly-striker.js.map +1 -1
  55. package/dist/cards/impl/minion/deflecto-bot.js.map +1 -1
  56. package/dist/cards/impl/minion/devout-hellcaller.js.map +1 -1
  57. package/dist/cards/impl/minion/drakkari-embalmer.js.map +1 -1
  58. package/dist/cards/impl/minion/electric-synthesizer.js.map +1 -1
  59. package/dist/cards/impl/minion/elite-navigator.js.map +1 -1
  60. package/dist/cards/impl/minion/fairy-gillmother.js.map +1 -1
  61. package/dist/cards/impl/minion/firescale-hoarder.js.map +1 -1
  62. package/dist/cards/impl/minion/fireworks-fanatic.js.map +1 -1
  63. package/dist/cards/impl/minion/flotsam-flinger.js.map +1 -1
  64. package/dist/cards/impl/minion/fountain-chiller.js.map +1 -1
  65. package/dist/cards/impl/minion/friendly-geist.js.map +1 -1
  66. package/dist/cards/impl/minion/gem-rat.js.map +1 -1
  67. package/dist/cards/impl/minion/general-drakkisath.js.map +1 -1
  68. package/dist/cards/impl/minion/gentle-djinni.js.map +1 -1
  69. package/dist/cards/impl/minion/gentle-stag.js.map +1 -1
  70. package/dist/cards/impl/minion/glim-guardian.d.ts +2 -0
  71. package/dist/cards/impl/minion/glim-guardian.js +13 -0
  72. package/dist/cards/impl/minion/glim-guardian.js.map +1 -0
  73. package/dist/cards/impl/minion/gormling-gourmet.js.map +1 -1
  74. package/dist/cards/impl/minion/greedy-snaketongue.js.map +1 -1
  75. package/dist/cards/impl/minion/grimscale-elegist.js.map +1 -1
  76. package/dist/cards/impl/minion/gritty-headhunter.js.map +1 -1
  77. package/dist/cards/impl/minion/hackerfin.js.map +1 -1
  78. package/dist/cards/impl/minion/handless-forsaken.js.map +1 -1
  79. package/dist/cards/impl/minion/harmless-bonehead.js.map +1 -1
  80. package/dist/cards/impl/minion/hawkstrider-herald.js.map +1 -1
  81. package/dist/cards/impl/minion/holo-rover.js.map +1 -1
  82. package/dist/cards/impl/minion/humongozz.js.map +1 -1
  83. package/dist/cards/impl/minion/hungry-snapjaw.js.map +1 -1
  84. package/dist/cards/impl/minion/hunter-of-gatherers.js.map +1 -1
  85. package/dist/cards/impl/minion/icesnarl-the-mighty.js +3 -1
  86. package/dist/cards/impl/minion/icesnarl-the-mighty.js.map +1 -1
  87. package/dist/cards/impl/minion/ignition-specialist.js.map +1 -1
  88. package/dist/cards/impl/minion/immortal.js.map +1 -1
  89. package/dist/cards/impl/minion/implant-subject.js.map +1 -1
  90. package/dist/cards/impl/minion/imposing-percussionist.js.map +1 -1
  91. package/dist/cards/impl/minion/inspiring-underdog.js.map +1 -1
  92. package/dist/cards/impl/minion/interrogator-whitemane.js.map +1 -1
  93. package/dist/cards/impl/minion/jailbird-juggernaut.js +7 -10
  94. package/dist/cards/impl/minion/jailbird-juggernaut.js.map +1 -1
  95. package/dist/cards/impl/minion/kangors-apprentice.js.map +1 -1
  96. package/dist/cards/impl/minion/leeroy-the-reckless.js.map +1 -1
  97. package/dist/cards/impl/minion/lightfang-enforcer.js.map +1 -1
  98. package/dist/cards/impl/minion/lightfeather-screecher.js.map +1 -1
  99. package/dist/cards/impl/minion/living-azerite.js.map +1 -1
  100. package/dist/cards/impl/minion/lokholar-frostforger.js.map +1 -1
  101. package/dist/cards/impl/minion/lovesick-balladist.js.map +1 -1
  102. package/dist/cards/impl/minion/low-flier.js.map +1 -1
  103. package/dist/cards/impl/minion/lurker.js.map +1 -1
  104. package/dist/cards/impl/minion/manasaber.js.map +1 -1
  105. package/dist/cards/impl/minion/mantid-queen.js.map +1 -1
  106. package/dist/cards/impl/minion/maritime-extortionist.d.ts +2 -0
  107. package/dist/cards/impl/minion/maritime-extortionist.js +33 -0
  108. package/dist/cards/impl/minion/maritime-extortionist.js.map +1 -0
  109. package/dist/cards/impl/minion/marquee-ticker.js.map +1 -1
  110. package/dist/cards/impl/minion/maw-caster.js.map +1 -1
  111. package/dist/cards/impl/minion/mecha-jaraxxus.js.map +1 -1
  112. package/dist/cards/impl/minion/mechanized-gift-horse.js.map +1 -1
  113. package/dist/cards/impl/minion/mechorse.js.map +1 -1
  114. package/dist/cards/impl/minion/menagerie-jug.js.map +1 -1
  115. package/dist/cards/impl/minion/metallic-hunter.js.map +1 -1
  116. package/dist/cards/impl/minion/misfit-dragonling.js.map +1 -1
  117. package/dist/cards/impl/minion/murkbrine-expeditioner.js.map +1 -1
  118. package/dist/cards/impl/minion/murky.js.map +1 -1
  119. package/dist/cards/impl/minion/mutated-lasher.js.map +1 -1
  120. package/dist/cards/impl/minion/mythrax.js.map +1 -1
  121. package/dist/cards/impl/minion/neon-agent.js.map +1 -1
  122. package/dist/cards/impl/minion/nest-swarmer.js.map +1 -1
  123. package/dist/cards/impl/minion/nether-drake.js.map +1 -1
  124. package/dist/cards/impl/minion/nightmare-par-tea-guest.js.map +1 -1
  125. package/dist/cards/impl/minion/nimble-hatchling.js.map +1 -1
  126. package/dist/cards/impl/minion/operatic-belcher.js.map +1 -1
  127. package/dist/cards/impl/minion/outback-smolderer.js.map +1 -1
  128. package/dist/cards/impl/minion/parched-wanderer.js.map +1 -1
  129. package/dist/cards/impl/minion/primalfin-lookout.js.map +1 -1
  130. package/dist/cards/impl/minion/rapscallion-recruiter.js.map +1 -1
  131. package/dist/cards/impl/minion/razorgore-the-untamed.js.map +1 -1
  132. package/dist/cards/impl/minion/roach.js.map +1 -1
  133. package/dist/cards/impl/minion/roadboar.js.map +1 -1
  134. package/dist/cards/impl/minion/rodeo-performer.js.map +1 -1
  135. package/dist/cards/impl/minion/ruins-renovator.js.map +1 -1
  136. package/dist/cards/impl/minion/rylak-metalhead.js.map +1 -1
  137. package/dist/cards/impl/minion/salty-hog.js.map +1 -1
  138. package/dist/cards/impl/minion/sand-swirler.js.map +1 -1
  139. package/dist/cards/impl/minion/sandy.js.map +1 -1
  140. package/dist/cards/impl/minion/scourge-harvester.js.map +1 -1
  141. package/dist/cards/impl/minion/selfless-hero.js.map +1 -1
  142. package/dist/cards/impl/minion/shadowdancer.js.map +1 -1
  143. package/dist/cards/impl/minion/sharp-eyed-sabretooth.js.map +1 -1
  144. package/dist/cards/impl/minion/sharptooth-snapper.js.map +1 -1
  145. package/dist/cards/impl/minion/ship-master-eudora.js.map +1 -1
  146. package/dist/cards/impl/minion/shipwrecked-rascal.js.map +1 -1
  147. package/dist/cards/impl/minion/silver-handed-recruit.js.map +1 -1
  148. package/dist/cards/impl/minion/slumber-sorcerer.js.map +1 -1
  149. package/dist/cards/impl/minion/smolderwing.js.map +1 -1
  150. package/dist/cards/impl/minion/soul-rewinder.js.map +1 -1
  151. package/dist/cards/impl/minion/spacefarer.js.map +1 -1
  152. package/dist/cards/impl/minion/spirited-whimsydrake.js.map +1 -1
  153. package/dist/cards/impl/minion/springy-spriggan.js.map +1 -1
  154. package/dist/cards/impl/minion/stitched-salvager.js.map +1 -1
  155. package/dist/cards/impl/minion/stray-satyr.js.map +1 -1
  156. package/dist/cards/impl/minion/sun-screener.js.map +1 -1
  157. package/dist/cards/impl/minion/surfing-slyvar.js.map +1 -1
  158. package/dist/cards/impl/minion/tasty-lobster.js +29 -3
  159. package/dist/cards/impl/minion/tasty-lobster.js.map +1 -1
  160. package/dist/cards/impl/minion/thorncaller.js.map +1 -1
  161. package/dist/cards/impl/minion/thousandth-paper-drake.js.map +1 -1
  162. package/dist/cards/impl/minion/thundering-abomination.js.map +1 -1
  163. package/dist/cards/impl/minion/timewarped-mrrrglr.js +1 -1
  164. package/dist/cards/impl/minion/timewarped-mrrrglr.js.map +1 -1
  165. package/dist/cards/impl/minion/timewarped-warghoul.js.map +1 -1
  166. package/dist/cards/impl/minion/tunnel-blaster.js.map +1 -1
  167. package/dist/cards/impl/minion/twilight-primordium.js.map +1 -1
  168. package/dist/cards/impl/minion/ultralisk.js.map +1 -1
  169. package/dist/cards/impl/minion/valiant-tiger.js.map +1 -1
  170. package/dist/cards/impl/minion/void-earl.js.map +1 -1
  171. package/dist/cards/impl/minion/vorkai-guardian.js.map +1 -1
  172. package/dist/cards/impl/minion/wandering-wight.js.map +1 -1
  173. package/dist/cards/impl/minion/whelp-smuggler.js.map +1 -1
  174. package/dist/cards/impl/minion/whirring-protector-enchantment.js.map +1 -1
  175. package/dist/cards/impl/minion/wildfire-elemental.js.map +1 -1
  176. package/dist/cards/impl/minion/wisp-in-the-shell.js.map +1 -1
  177. package/dist/cards/impl/minion/yorik-smite.js.map +1 -1
  178. package/dist/cards/impl/minion/yrel.js.map +1 -1
  179. package/dist/cards/impl/minion/yulon-fortune-granter.js.map +1 -1
  180. package/dist/cards/impl/quest-reward/righteous-charge.js.map +1 -1
  181. package/dist/cards/impl/secret/ice-block.d.ts +2 -0
  182. package/dist/cards/impl/secret/ice-block.js +7 -0
  183. package/dist/cards/impl/secret/ice-block.js.map +1 -0
  184. package/dist/cards/impl/trinket/all-purpose-kibble.js.map +1 -1
  185. package/dist/cards/impl/trinket/arm-of-the-empire.js.map +1 -1
  186. package/dist/cards/impl/trinket/bassgill-portrait.js.map +1 -1
  187. package/dist/cards/impl/trinket/battle-horn.js.map +1 -1
  188. package/dist/cards/impl/trinket/bird-feeder.js.map +1 -1
  189. package/dist/cards/impl/trinket/crocheted-sungill.js.map +1 -1
  190. package/dist/cards/impl/trinket/eclectic-shrine.js.map +1 -1
  191. package/dist/cards/impl/trinket/faerie-dragon-scale.js.map +1 -1
  192. package/dist/cards/impl/trinket/fishy-sticker.js.map +1 -1
  193. package/dist/cards/impl/trinket/herald-sticker.js.map +1 -1
  194. package/dist/cards/impl/trinket/karazhan-chess-set.js.map +1 -1
  195. package/dist/cards/impl/trinket/rivendare-portrait.js.map +1 -1
  196. package/dist/cards/impl/trinket/sthara-sticker.js.map +1 -1
  197. package/dist/cards/impl/trinket/valorous-medaillion.js.map +1 -1
  198. package/dist/cards/impl/trinket/vashjir-anemone.js.map +1 -1
  199. package/dist/cards/impl/trinket/yulon-sticker.js.map +1 -1
  200. package/dist/debug-state.js.map +1 -1
  201. package/dist/input-clone.js +6 -3
  202. package/dist/input-clone.js.map +1 -1
  203. package/dist/keywords/venomous.js.map +1 -1
  204. package/dist/simulate-bgs-battle.js +2 -1
  205. package/dist/simulate-bgs-battle.js.map +1 -1
  206. package/dist/simulation/add-minion-to-board.js +5 -5
  207. package/dist/simulation/add-minion-to-board.js.map +1 -1
  208. package/dist/simulation/auras.js +7 -6
  209. package/dist/simulation/auras.js.map +1 -1
  210. package/dist/simulation/deathrattle-on-trigger.js.map +1 -1
  211. package/dist/simulation/discover.js.map +1 -1
  212. package/dist/simulation/frenzy.js.map +1 -1
  213. package/dist/simulation/internal-game-state.d.ts +1 -0
  214. package/dist/simulation/internal-game-state.js.map +1 -1
  215. package/dist/simulation/quest.js.map +1 -1
  216. package/dist/simulation/secrets.d.ts +1 -0
  217. package/dist/simulation/secrets.js +14 -1
  218. package/dist/simulation/secrets.js.map +1 -1
  219. package/dist/simulation/simulator.js +25 -9
  220. package/dist/simulation/simulator.js.map +1 -1
  221. package/dist/simulation/start-of-combat/soc-action-processor.js +3 -0
  222. package/dist/simulation/start-of-combat/soc-action-processor.js.map +1 -1
  223. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/simulation/discover.ts"],"names":[],"mappings":";;;AAGA,mDAAiD;AAEjD,mCAAsC;AAE/B,MAAM,aAAa,GAAG,CAC5B,IAAqB,EACrB,KAAoB,EACpB,MAAc,EACd,OAAiB,EACjB,SAAwB,EACvB,EAAE;IACH,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAA,EAAE;QACrB,OAAO;KACP;IAED,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE;QAC3B,QAAQ,MAAM,CAAC,MAAM,EAAE;YACtB,gBAAqC;YACrC;gBACC,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,eAAoC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnF,MAAM,eAAe,GAAG,OAAO;qBAC7B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;qBAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,MAAM,eAAe,GAAG,OAAO;qBAC7B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;qBAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,IAAA,mBAAW,EACV,MAAM,EACN,MAAM,EACN,eAAe,GAAG,gBAAgB,EAClC,eAAe,GAAG,gBAAgB,EAClC,KAAK,EACL,IAAI,EACJ,SAAS,CACT,CAAC;gBACF,MAAM;SACP;KACD;IAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAAiD,CAChE,CAAC,MAAM,CAAC;IACT,IAAI,CAAC,CAAC,kBAAkB,EAAE;QACzB,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAA,8BAAc,EAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;KACnD;AACF,CAAC,CAAC;AA1CW,QAAA,aAAa,iBA0CxB","sourcesContent":["import { CardIds } from '../services/card-ids';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const afterDiscover = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tpicked: string,\r\n\tignored: string[],\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (!ignored?.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tfor (const entity of board) {\r\n\t\tswitch (entity.cardId) {\r\n\t\t\tcase CardIds.DepravedFelfin_BG30_115:\r\n\t\t\tcase CardIds.DepravedFelfin_BG30_115_G:\r\n\t\t\t\tconst felfinMultiplier = entity.cardId === CardIds.DepravedFelfin_BG30_115 ? 1 : 2;\r\n\t\t\t\tconst baseTotalAttack = ignored\r\n\t\t\t\t\t.map((cardId) => gameState.allCards.getCard(cardId).attack)\r\n\t\t\t\t\t.reduce((a, b) => a + b, 0);\r\n\t\t\t\tconst baseTotalHealth = ignored\r\n\t\t\t\t\t.map((cardId) => gameState.allCards.getCard(cardId).health)\r\n\t\t\t\t\t.reduce((a, b) => a + b, 0);\r\n\t\t\t\tmodifyStats(\r\n\t\t\t\t\tentity,\r\n\t\t\t\t\tentity,\r\n\t\t\t\t\tbaseTotalAttack * felfinMultiplier,\r\n\t\t\t\t\tbaseTotalHealth * felfinMultiplier,\r\n\t\t\t\t\tboard,\r\n\t\t\t\t\thero,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tconst primalfinPortraits = hero.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PrimalfinPortrait_BG30_MagicItem_702,\r\n\t).length;\r\n\tif (!!primalfinPortraits) {\r\n\t\tconst cardsToAdd = new Array(primalfinPortraits).fill(null);\r\n\t\taddCardsInHand(hero, board, cardsToAdd, gameState);\r\n\t}\r\n};\r\n"]}
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/simulation/discover.ts"],"names":[],"mappings":";;;AAGA,mDAAiD;AAEjD,mCAAsC;AAE/B,MAAM,aAAa,GAAG,CAC5B,IAAqB,EACrB,KAAoB,EACpB,MAAc,EACd,OAAiB,EACjB,SAAwB,EACvB,EAAE;IACH,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAA,EAAE;QACrB,OAAO;KACP;IAED,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE;QAC3B,QAAQ,MAAM,CAAC,MAAM,EAAE;YACtB,gBAAqC;YACrC;gBACC,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,eAAoC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnF,MAAM,eAAe,GAAG,OAAO;qBAC7B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;qBAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,MAAM,eAAe,GAAG,OAAO;qBAC7B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;qBAC1D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7B,IAAA,mBAAW,EACV,MAAM,EACN,MAAM,EACN,eAAe,GAAG,gBAAgB,EAClC,eAAe,GAAG,gBAAgB,EAClC,KAAK,EACL,IAAI,EACJ,SAAS,CACT,CAAC;gBACF,MAAM;SACP;KACD;IAED,MAAM,kBAAkB,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAAiD,CAChE,CAAC,MAAM,CAAC;IACT,IAAI,CAAC,CAAC,kBAAkB,EAAE;QACzB,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5D,IAAA,8BAAc,EAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;KACnD;AACF,CAAC,CAAC;AA1CW,QAAA,aAAa,iBA0CxB","sourcesContent":["import { CardIds } from '../services/card-ids';\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const afterDiscover = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tpicked: string,\r\n\tignored: string[],\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (!ignored?.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tfor (const entity of board) {\r\n\t\tswitch (entity.cardId) {\r\n\t\t\tcase CardIds.DepravedFelfin_BG30_115:\r\n\t\t\tcase CardIds.DepravedFelfin_BG30_115_G:\r\n\t\t\t\tconst felfinMultiplier = entity.cardId === CardIds.DepravedFelfin_BG30_115 ? 1 : 2;\r\n\t\t\t\tconst baseTotalAttack = ignored\r\n\t\t\t\t\t.map((cardId) => gameState.allCards.getCard(cardId).attack)\r\n\t\t\t\t\t.reduce((a, b) => a + b, 0);\r\n\t\t\t\tconst baseTotalHealth = ignored\r\n\t\t\t\t\t.map((cardId) => gameState.allCards.getCard(cardId).health)\r\n\t\t\t\t\t.reduce((a, b) => a + b, 0);\r\n\t\t\t\tmodifyStats(\r\n\t\t\t\t\tentity,\r\n\t\t\t\t\tentity,\r\n\t\t\t\t\tbaseTotalAttack * felfinMultiplier,\r\n\t\t\t\t\tbaseTotalHealth * felfinMultiplier,\r\n\t\t\t\t\tboard,\r\n\t\t\t\t\thero,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tconst primalfinPortraits = hero.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PrimalfinPortrait_BG30_MagicItem_702,\r\n\t).length;\r\n\tif (!!primalfinPortraits) {\r\n\t\tconst cardsToAdd = new Array(primalfinPortraits).fill(null);\r\n\t\taddCardsInHand(hero, board, cardsToAdd, gameState);\r\n\t}\r\n};\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"frenzy.js","sourceRoot":"","sources":["../../src/simulation/frenzy.ts"],"names":[],"mappings":";;;AAIA,6DAA+D;AAGxD,MAAM,WAAW,GAAG,CAC1B,gBAA6B,EAC7B,qBAAoC,EACpC,yBAA0C,EAC1C,SAAwB,EACjB,EAAE;IACT,IACC,gBAAgB,CAAC,MAAM,eAAuC;QAC9D,gBAAgB,CAAC,MAAM,iBAAyC,EAC/D;QACD,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE;YACnC,IAAA,kCAAkB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,IAAI,EACJ,IAAI,EACJ,SAAS,CACT,CAAC;SACF;KACD;AACF,CAAC,CAAC;AArBW,QAAA,WAAW,eAqBtB","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { CardIds } from '../services/card-ids';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { FullGameState } from './internal-game-state';\r\n\r\nexport const applyFrenzy = (\r\n\tentityWithFrenzy: BoardEntity,\r\n\tentityWithFrenzyBoard: BoardEntity[],\r\n\tentityWithFrenzyBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (\r\n\t\tentityWithFrenzy.cardId === CardIds.BristlebackKnight_BG20_204 ||\r\n\t\tentityWithFrenzy.cardId === CardIds.BristlebackKnight_BG20_204_G\r\n\t) {\r\n\t\tif (!entityWithFrenzy.divineShield) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tentityWithFrenzy,\r\n\t\t\t\tentityWithFrenzyBoard,\r\n\t\t\t\tentityWithFrenzyBoardHero,\r\n\t\t\t\tnull,\r\n\t\t\t\ttrue,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n};\r\n"]}
1
+ {"version":3,"file":"frenzy.js","sourceRoot":"","sources":["../../src/simulation/frenzy.ts"],"names":[],"mappings":";;;AAIA,6DAA+D;AAGxD,MAAM,WAAW,GAAG,CAC1B,gBAA6B,EAC7B,qBAAoC,EACpC,yBAA0C,EAC1C,SAAwB,EACjB,EAAE;IACT,IACC,gBAAgB,CAAC,MAAM,eAAuC;QAC9D,gBAAgB,CAAC,MAAM,iBAAyC,EAC/D;QACD,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE;YACnC,IAAA,kCAAkB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,IAAI,EACJ,IAAI,EACJ,SAAS,CACT,CAAC;SACF;KACD;AACF,CAAC,CAAC;AArBW,QAAA,WAAW,eAqBtB","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { CardIds } from '../services/card-ids';\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { FullGameState } from './internal-game-state';\r\n\r\nexport const applyFrenzy = (\r\n\tentityWithFrenzy: BoardEntity,\r\n\tentityWithFrenzyBoard: BoardEntity[],\r\n\tentityWithFrenzyBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (\r\n\t\tentityWithFrenzy.cardId === CardIds.BristlebackKnight_BG20_204 ||\r\n\t\tentityWithFrenzy.cardId === CardIds.BristlebackKnight_BG20_204_G\r\n\t) {\r\n\t\tif (!entityWithFrenzy.divineShield) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tentityWithFrenzy,\r\n\t\t\t\tentityWithFrenzyBoard,\r\n\t\t\t\tentityWithFrenzyBoardHero,\r\n\t\t\t\tnull,\r\n\t\t\t\ttrue,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n};\r\n"]}
@@ -12,6 +12,7 @@ export interface FullGameState {
12
12
  currentTurn: number;
13
13
  numberOfPlayersAlive?: number;
14
14
  applyDamageCap?: boolean;
15
+ applyIceBlock?: boolean;
15
16
  validTribes: readonly Race[];
16
17
  anomalies: readonly string[];
17
18
  gameState: GameState;
@@ -1 +1 @@
1
- {"version":3,"file":"internal-game-state.js","sourceRoot":"","sources":["../../src/simulation/internal-game-state.ts"],"names":[],"mappings":"","sourcesContent":["import { AllCardsService, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardsData } from '../cards/cards-data';\r\nimport { SharedState } from './shared-state';\r\nimport { Spectator } from './spectator/spectator';\r\n\r\nexport interface FullGameState {\r\n\tallCards: AllCardsService;\r\n\tcardsData: CardsData;\r\n\tspectator: Spectator;\r\n\tsharedState: SharedState;\r\n\tcurrentTurn: number;\r\n\t/** Heroes still alive in the lobby; used when applyDamageCap is set. */\r\n\tnumberOfPlayersAlive?: number;\r\n\t/** When true, apply the Battlegrounds lobby damage cap. Default off. */\r\n\tapplyDamageCap?: boolean;\r\n\tvalidTribes: readonly Race[];\r\n\tanomalies: readonly string[];\r\n\tgameState: GameState;\r\n}\r\n\r\nexport interface GameState {\r\n\tplayer: PlayerState;\r\n\topponent: PlayerState;\r\n\tplayerInitial: PlayerState;\r\n\topponentInitial: PlayerState;\r\n}\r\n\r\nexport interface PlayerState {\r\n\tboard: BoardEntity[];\r\n\tplayer: BgsPlayerEntity;\r\n\tteammate?: PlayerState;\r\n}\r\n"]}
1
+ {"version":3,"file":"internal-game-state.js","sourceRoot":"","sources":["../../src/simulation/internal-game-state.ts"],"names":[],"mappings":"","sourcesContent":["import { AllCardsService, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardsData } from '../cards/cards-data';\r\nimport { SharedState } from './shared-state';\r\nimport { Spectator } from './spectator/spectator';\r\n\r\nexport interface FullGameState {\r\n\tallCards: AllCardsService;\r\n\tcardsData: CardsData;\r\n\tspectator: Spectator;\r\n\tsharedState: SharedState;\r\n\tcurrentTurn: number;\r\n\t/** Heroes still alive in the lobby; used when applyDamageCap is set. */\r\n\tnumberOfPlayersAlive?: number;\r\n\t/** When true, apply the Battlegrounds lobby damage cap. Default off. */\r\n\tapplyDamageCap?: boolean;\r\n\t/** When true, Ice Block can prevent end-of-combat face damage. Default off. */\r\n\tapplyIceBlock?: boolean;\r\n\tvalidTribes: readonly Race[];\r\n\tanomalies: readonly string[];\r\n\tgameState: GameState;\r\n}\r\n\r\nexport interface GameState {\r\n\tplayer: PlayerState;\r\n\topponent: PlayerState;\r\n\tplayerInitial: PlayerState;\r\n\topponentInitial: PlayerState;\r\n}\r\n\r\nexport interface PlayerState {\r\n\tboard: BoardEntity[];\r\n\tplayer: BgsPlayerEntity;\r\n\tteammate?: PlayerState;\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"quest.js","sourceRoot":"","sources":["../../src/simulation/quest.ts"],"names":[],"mappings":";;;AAKO,MAAM,sBAAsB,GAAG,CACrC,YAA6B,EAC7B,KAAqB,EACrB,KAAoB,EACpB,SAAwB,EACvB,EAAE;IACH,KAAK,CAAC,eAAe,EAAE,CAAC;IACxB,IAAI,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,aAAa,EAAE;QAChD,OAAO;KACP;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;IACtE,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7C,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC;QACrC,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe,EAAE;QACjD,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,YAAY,CAAC;QAC5D,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,YAAY,CAAC;QAC5D,cAAc,EAAE,SAAS,CAAC,SAAS,CAAC,oBAAoB,CAAC,YAAY,CAAC;KACtE,CAAC,CAAC;IAGH,YAAY,CAAC,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC;IAEjG,4BAA4B,CAAC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;AAC5E,CAAC,CAAC;AAzBW,QAAA,sBAAsB,0BAyBjC;AAEF,MAAM,4BAA4B,GAAG,CACpC,YAAoB,EACpB,KAAoB,EACpB,YAA6B,EAC7B,SAAwB,EACvB,EAAE;IACH,QAAQ,YAAY,EAAE;QACrB;YACC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACnB,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;YACH,MAAM;QACP;YACC,MAAM;KACP;AACF,CAAC,CAAC","sourcesContent":["import { CardIds } from '../services/card-ids';\r\nimport { BgsPlayerEntity, BgsQuestEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { FullGameState } from './internal-game-state';\r\n\r\nexport const onQuestProgressUpdated = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tquest: BgsQuestEntity,\r\n\tboard: BoardEntity[],\r\n\tgameState: FullGameState,\r\n) => {\r\n\tquest.ProgressCurrent++;\r\n\tif (quest.ProgressCurrent < quest.ProgressTotal) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst rewardCardId = gameState.allCards.getCard(quest.RewardDbfId).id;\r\n\tplayerEntity.questRewards.push(rewardCardId);\r\n\tplayerEntity.questRewardEntities.push({\r\n\t\tcardId: rewardCardId,\r\n\t\tentityId: gameState.sharedState.currentEntityId++,\r\n\t\tavengeDefault: gameState.cardsData.avengeValue(rewardCardId),\r\n\t\tavengeCurrent: gameState.cardsData.avengeValue(rewardCardId),\r\n\t\tscriptDataNum1: gameState.cardsData.defaultScriptDataNum(rewardCardId),\r\n\t});\r\n\r\n\t// Remove the quest from the list of quests\r\n\tplayerEntity.questEntities = playerEntity.questEntities.filter((q) => q.CardId !== quest.CardId);\r\n\r\n\tupdateStateAfterQuestCreated(rewardCardId, board, playerEntity, gameState);\r\n};\r\n\r\nconst updateStateAfterQuestCreated = (\r\n\trewardCardId: string,\r\n\tboard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tswitch (rewardCardId) {\r\n\t\tcase CardIds.TheSmokingGun:\r\n\t\t\tboard.forEach((e) => {\r\n\t\t\t\te.attack += 4;\r\n\t\t\t});\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\tbreak;\r\n\t}\r\n};\r\n"]}
1
+ {"version":3,"file":"quest.js","sourceRoot":"","sources":["../../src/simulation/quest.ts"],"names":[],"mappings":";;;AAKO,MAAM,sBAAsB,GAAG,CACrC,YAA6B,EAC7B,KAAqB,EACrB,KAAoB,EACpB,SAAwB,EACvB,EAAE;IACH,KAAK,CAAC,eAAe,EAAE,CAAC;IACxB,IAAI,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,aAAa,EAAE;QAChD,OAAO;KACP;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;IACtE,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7C,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC;QACrC,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe,EAAE;QACjD,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,YAAY,CAAC;QAC5D,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,YAAY,CAAC;QAC5D,cAAc,EAAE,SAAS,CAAC,SAAS,CAAC,oBAAoB,CAAC,YAAY,CAAC;KACtE,CAAC,CAAC;IAGH,YAAY,CAAC,aAAa,GAAG,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC;IAEjG,4BAA4B,CAAC,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;AAC5E,CAAC,CAAC;AAzBW,QAAA,sBAAsB,0BAyBjC;AAEF,MAAM,4BAA4B,GAAG,CACpC,YAAoB,EACpB,KAAoB,EACpB,YAA6B,EAC7B,SAAwB,EACvB,EAAE;IACH,QAAQ,YAAY,EAAE;QACrB;YACC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACnB,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;YACf,CAAC,CAAC,CAAC;YACH,MAAM;QACP;YACC,MAAM;KACP;AACF,CAAC,CAAC","sourcesContent":["import { CardIds } from '../services/card-ids';\nimport { BgsPlayerEntity, BgsQuestEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { FullGameState } from './internal-game-state';\r\n\r\nexport const onQuestProgressUpdated = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tquest: BgsQuestEntity,\r\n\tboard: BoardEntity[],\r\n\tgameState: FullGameState,\r\n) => {\r\n\tquest.ProgressCurrent++;\r\n\tif (quest.ProgressCurrent < quest.ProgressTotal) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst rewardCardId = gameState.allCards.getCard(quest.RewardDbfId).id;\r\n\tplayerEntity.questRewards.push(rewardCardId);\r\n\tplayerEntity.questRewardEntities.push({\r\n\t\tcardId: rewardCardId,\r\n\t\tentityId: gameState.sharedState.currentEntityId++,\r\n\t\tavengeDefault: gameState.cardsData.avengeValue(rewardCardId),\r\n\t\tavengeCurrent: gameState.cardsData.avengeValue(rewardCardId),\r\n\t\tscriptDataNum1: gameState.cardsData.defaultScriptDataNum(rewardCardId),\r\n\t});\r\n\r\n\t// Remove the quest from the list of quests\r\n\tplayerEntity.questEntities = playerEntity.questEntities.filter((q) => q.CardId !== quest.CardId);\r\n\r\n\tupdateStateAfterQuestCreated(rewardCardId, board, playerEntity, gameState);\r\n};\r\n\r\nconst updateStateAfterQuestCreated = (\r\n\trewardCardId: string,\r\n\tboard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tswitch (rewardCardId) {\r\n\t\tcase CardIds.TheSmokingGun:\r\n\t\t\tboard.forEach((e) => {\r\n\t\t\t\te.attack += 4;\r\n\t\t\t});\r\n\t\t\tbreak;\r\n\t\tdefault:\r\n\t\t\tbreak;\r\n\t}\r\n};\r\n"]}
@@ -1,6 +1,7 @@
1
1
  import { BgsPlayerEntity } from '../bgs-player-entity';
2
2
  import { BoardEntity } from '../board-entity';
3
3
  import { FullGameState } from './internal-game-state';
4
+ export declare const tryPreventCombatDamageWithIceBlock: (hero: BgsPlayerEntity | null | undefined) => boolean;
4
5
  export declare const handleSplittingImage: (defendingEntity: BoardEntity, defendingBoard: BoardEntity[], defendingPlayerEntity: BgsPlayerEntity, attackerBoard: BoardEntity[], attackerHero: BgsPlayerEntity, gameState: FullGameState) => void;
5
6
  export declare const handlePackTactics: (defendingEntity: BoardEntity, defendingBoard: BoardEntity[], defendingPlayerEntity: BgsPlayerEntity, attackerBoard: BoardEntity[], attackerHero: BgsPlayerEntity, gameState: FullGameState, secretCardId: string) => void;
6
7
  export declare const handleSnakeTrap: (defendingEntity: BoardEntity, defendingBoard: BoardEntity[], defendingPlayerEntity: BgsPlayerEntity, attackerBoard: BoardEntity[], attackerHero: BgsPlayerEntity, gameState: FullGameState) => void;
@@ -1,10 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleVenomstrikeTrap = exports.handleSnakeTrap = exports.handlePackTactics = exports.handleSplittingImage = void 0;
3
+ exports.handleVenomstrikeTrap = exports.handleSnakeTrap = exports.handlePackTactics = exports.handleSplittingImage = exports.tryPreventCombatDamageWithIceBlock = void 0;
4
4
  const utils_1 = require("../utils");
5
5
  const add_minion_to_board_1 = require("./add-minion-to-board");
6
6
  const deathrattle_spawns_1 = require("./deathrattle-spawns");
7
7
  const spawns_1 = require("./spawns");
8
+ const tryPreventCombatDamageWithIceBlock = (hero) => {
9
+ var _a;
10
+ if (!hero) {
11
+ return false;
12
+ }
13
+ const secret = ((_a = hero.secrets) !== null && _a !== void 0 ? _a : []).find((s) => s.cardId === "TB_Bacon_Secrets_12" && !s.triggered);
14
+ if (!secret) {
15
+ return false;
16
+ }
17
+ secret.triggered = true;
18
+ return true;
19
+ };
20
+ exports.tryPreventCombatDamageWithIceBlock = tryPreventCombatDamageWithIceBlock;
8
21
  const handleSplittingImage = (defendingEntity, defendingBoard, defendingPlayerEntity, attackerBoard, attackerHero, gameState) => {
9
22
  const copy = {
10
23
  ...defendingEntity,
@@ -1 +1 @@
1
- {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/simulation/secrets.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { copyEntity } from '../utils';\r\nimport { removeAurasFromSelf } from './add-minion-to-board';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { performEntitySpawns } from './spawns';\r\n\r\nexport const handleSplittingImage = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst copy: BoardEntity = {\r\n\t\t...defendingEntity,\r\n\t\tattack: 3,\r\n\t\thealth: 3,\r\n\t\tmaxHealth: 3,\r\n\t};\r\n\tconst candidateEntities = spawnEntities(\r\n\t\tdefendingEntity.cardId,\r\n\t\t1,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t\tcopy,\r\n\t);\r\n\tconst indexFromRight = defendingBoard.length - (defendingBoard.indexOf(defendingEntity) + 1);\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\tindexFromRight,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport const handlePackTactics = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tsecretCardId: string,\r\n): void => {\r\n\tconst copy: BoardEntity = copyEntity(defendingEntity);\r\n\tremoveAurasFromSelf(copy, defendingBoard, defendingPlayerEntity, gameState);\r\n\tconst candidateEntities = spawnEntities(\r\n\t\tcopy.cardId,\r\n\t\t1,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t\tcopy,\r\n\t);\r\n\tif (secretCardId === CardIds.PackTactics_TB_Bacon_Secrets_15) {\r\n\t\t// Don't use setEntityStats, because it will be applied when adding the minion to the board\r\n\t\tcandidateEntities.forEach((e) => {\r\n\t\t\te.health = 3;\r\n\t\t\te.maxHealth = 3;\r\n\t\t\te.attack = 3;\r\n\t\t\te.maxAttack = 3;\r\n\t\t});\r\n\t\t//setEntityStats(e, 3, 3, defendingBoard, defendingPlayerEntity, gameState));\r\n\t}\r\n\tconst indexFromRight = defendingBoard.length - (defendingBoard.indexOf(defendingEntity) + 1);\r\n\tconst spawned = performEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\tindexFromRight,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n\tspawned.forEach((e) => {\r\n\t\t// Might be a HS bug\r\n\t\t// 33.6.2 https://replays.firestoneapp.com/?reviewId=06e89a29-8f63-4c55-bdac-d908ed6e5857&turn=9&action=1\r\n\t\te.hasAttacked = defendingEntity.hasAttacked;\r\n\t});\r\n};\r\n\r\nexport const handleSnakeTrap = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst candidateEntities: readonly BoardEntity[] = spawnEntities(\r\n\t\tCardIds.SnakeTrap_SnakeLegacyToken,\r\n\t\t3,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t);\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\t0,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport const handleVenomstrikeTrap = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities: readonly BoardEntity[] = spawnEntities(\r\n\t\tCardIds.EmperorCobraLegacy_BG_EX1_170,\r\n\t\t1,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t);\r\n\tconst spawns = performEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\t0,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n\treturn spawns;\r\n};\r\n"]}
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/simulation/secrets.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { copyEntity } from '../utils';\r\nimport { removeAurasFromSelf } from './add-minion-to-board';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { performEntitySpawns } from './spawns';\r\n\r\n/**\r\n * Ice Block (TB_Bacon_Secrets_12): the first time your hero would take damage, prevent it.\r\n * Combat face damage is applied once at end of fight — consume the secret then.\r\n * Callers must gate this behind `options.applyIceBlock` (full-game / Layer C only);\r\n * Firestone battle sims leave damage uncapped for odds.\r\n */\r\nexport const tryPreventCombatDamageWithIceBlock = (hero: BgsPlayerEntity | null | undefined): boolean => {\r\n\tif (!hero) {\r\n\t\treturn false;\r\n\t}\r\n\tconst secret = (hero.secrets ?? []).find(\r\n\t\t(s) => s.cardId === CardIds.IceBlock && !s.triggered,\r\n\t);\r\n\tif (!secret) {\r\n\t\treturn false;\r\n\t}\r\n\tsecret.triggered = true;\r\n\treturn true;\r\n};\r\n\r\nexport const handleSplittingImage = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst copy: BoardEntity = {\r\n\t\t...defendingEntity,\r\n\t\tattack: 3,\r\n\t\thealth: 3,\r\n\t\tmaxHealth: 3,\r\n\t};\r\n\tconst candidateEntities = spawnEntities(\r\n\t\tdefendingEntity.cardId,\r\n\t\t1,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t\tcopy,\r\n\t);\r\n\tconst indexFromRight = defendingBoard.length - (defendingBoard.indexOf(defendingEntity) + 1);\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\tindexFromRight,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport const handlePackTactics = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tsecretCardId: string,\r\n): void => {\r\n\tconst copy: BoardEntity = copyEntity(defendingEntity);\r\n\tremoveAurasFromSelf(copy, defendingBoard, defendingPlayerEntity, gameState);\r\n\tconst candidateEntities = spawnEntities(\r\n\t\tcopy.cardId,\r\n\t\t1,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t\tcopy,\r\n\t);\r\n\tif (secretCardId === CardIds.PackTactics_TB_Bacon_Secrets_15) {\r\n\t\t// Don't use setEntityStats, because it will be applied when adding the minion to the board\r\n\t\tcandidateEntities.forEach((e) => {\r\n\t\t\te.health = 3;\r\n\t\t\te.maxHealth = 3;\r\n\t\t\te.attack = 3;\r\n\t\t\te.maxAttack = 3;\r\n\t\t});\r\n\t\t//setEntityStats(e, 3, 3, defendingBoard, defendingPlayerEntity, gameState));\r\n\t}\r\n\tconst indexFromRight = defendingBoard.length - (defendingBoard.indexOf(defendingEntity) + 1);\r\n\tconst spawned = performEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\tindexFromRight,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n\tspawned.forEach((e) => {\r\n\t\t// Might be a HS bug\r\n\t\t// 33.6.2 https://replays.firestoneapp.com/?reviewId=06e89a29-8f63-4c55-bdac-d908ed6e5857&turn=9&action=1\r\n\t\te.hasAttacked = defendingEntity.hasAttacked;\r\n\t});\r\n};\r\n\r\nexport const handleSnakeTrap = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst candidateEntities: readonly BoardEntity[] = spawnEntities(\r\n\t\tCardIds.SnakeTrap_SnakeLegacyToken,\r\n\t\t3,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t);\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\t0,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport const handleVenomstrikeTrap = (\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingPlayerEntity: BgsPlayerEntity,\r\n\tattackerBoard: BoardEntity[],\r\n\tattackerHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities: readonly BoardEntity[] = spawnEntities(\r\n\t\tCardIds.EmperorCobraLegacy_BG_EX1_170,\r\n\t\t1,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t\tdefendingEntity.friendly,\r\n\t\tfalse,\r\n\t);\r\n\tconst spawns = performEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tdefendingBoard,\r\n\t\tdefendingPlayerEntity,\r\n\t\tdefendingEntity,\r\n\t\t0,\r\n\t\tattackerBoard,\r\n\t\tattackerHero,\r\n\t\tgameState,\r\n\t);\r\n\treturn spawns;\r\n};\r\n"]}
@@ -8,6 +8,7 @@ const attack_1 = require("./attack");
8
8
  const auras_1 = require("./auras");
9
9
  const damage_cap_1 = require("./damage-cap");
10
10
  const pending_effects_1 = require("./pending-effects");
11
+ const secrets_1 = require("./secrets");
11
12
  const start_of_combat_1 = require("./start-of-combat/start-of-combat");
12
13
  const summon_when_space_1 = require("./summon-when-space");
13
14
  class Simulator {
@@ -17,7 +18,7 @@ class Simulator {
17
18
  this.hasShowShortCircuitWarning = false;
18
19
  }
19
20
  simulateSingleBattle(playerState, opponentState) {
20
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
21
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
21
22
  let playerBoard = playerState.board;
22
23
  let playerEntity = playerState.player;
23
24
  let opponentBoard = opponentState.board;
@@ -74,7 +75,7 @@ class Simulator {
74
75
  opponentBoard = opponentState.board;
75
76
  opponentEntity = opponentState.player;
76
77
  }
77
- if (isPlayerDefeated) {
78
+ if (isPlayerDefeated && playerEntity) {
78
79
  this.gameState.sharedState.deaths = this.gameState.sharedState.deaths.filter((e) => e.friendly !== this.gameState.gameState.player.player.friendly);
79
80
  this.gameState.gameState.player.teammate = {
80
81
  board: this.gameState.gameState.player.board,
@@ -83,7 +84,7 @@ class Simulator {
83
84
  this.gameState.gameState.player.player = playerEntity;
84
85
  this.gameState.gameState.player.board = playerBoard;
85
86
  }
86
- if (isOpponentDefeated) {
87
+ if (isOpponentDefeated && opponentEntity) {
87
88
  this.gameState.sharedState.deaths = this.gameState.sharedState.deaths.filter((e) => e.friendly !== this.gameState.gameState.opponent.player.friendly);
88
89
  this.gameState.gameState.opponent.teammate = {
89
90
  board: this.gameState.gameState.opponent.board,
@@ -102,17 +103,31 @@ class Simulator {
102
103
  result: 'tied',
103
104
  };
104
105
  }
105
- if (!(playerBoard === null || playerBoard === void 0 ? void 0 : playerBoard.length) || playerEntity.hpLeft <= 0) {
106
- const damage = this.capDamage(this.buildBoardTotalDamage(opponentBoard, (_g = (_f = this.gameState.gameState.opponent) === null || _f === void 0 ? void 0 : _f.teammate) === null || _g === void 0 ? void 0 : _g.board) +
107
- opponentEntity.tavernTier);
106
+ if (!(playerBoard === null || playerBoard === void 0 ? void 0 : playerBoard.length) || (playerEntity === null || playerEntity === void 0 ? void 0 : playerEntity.hpLeft) <= 0) {
107
+ const winningHero = opponentEntity !== null && opponentEntity !== void 0 ? opponentEntity : opponentState.player;
108
+ const losingHero = playerEntity !== null && playerEntity !== void 0 ? playerEntity : playerState.player;
109
+ let damage = this.capDamage(this.buildBoardTotalDamage(opponentBoard, (_g = (_f = this.gameState.gameState.opponent) === null || _f === void 0 ? void 0 : _f.teammate) === null || _g === void 0 ? void 0 : _g.board) +
110
+ ((_h = winningHero === null || winningHero === void 0 ? void 0 : winningHero.tavernTier) !== null && _h !== void 0 ? _h : 1));
111
+ if (this.gameState.applyIceBlock &&
112
+ damage > 0 &&
113
+ (0, secrets_1.tryPreventCombatDamageWithIceBlock)(losingHero)) {
114
+ damage = 0;
115
+ }
108
116
  this.gameState.spectator.registerOpponentAttack(playerBoard, opponentBoard, damage);
109
117
  return {
110
118
  result: 'lost',
111
119
  damageDealt: damage,
112
120
  };
113
121
  }
114
- const damage = this.capDamage(this.buildBoardTotalDamage(playerBoard, (_j = (_h = this.gameState.gameState.player) === null || _h === void 0 ? void 0 : _h.teammate) === null || _j === void 0 ? void 0 : _j.board) +
115
- playerEntity.tavernTier);
122
+ const winningHero = playerEntity !== null && playerEntity !== void 0 ? playerEntity : playerState.player;
123
+ const losingHero = opponentEntity !== null && opponentEntity !== void 0 ? opponentEntity : opponentState.player;
124
+ let damage = this.capDamage(this.buildBoardTotalDamage(playerBoard, (_k = (_j = this.gameState.gameState.player) === null || _j === void 0 ? void 0 : _j.teammate) === null || _k === void 0 ? void 0 : _k.board) +
125
+ ((_l = winningHero === null || winningHero === void 0 ? void 0 : winningHero.tavernTier) !== null && _l !== void 0 ? _l : 1));
126
+ if (this.gameState.applyIceBlock &&
127
+ damage > 0 &&
128
+ (0, secrets_1.tryPreventCombatDamageWithIceBlock)(losingHero)) {
129
+ damage = 0;
130
+ }
116
131
  this.gameState.spectator.registerPlayerAttack(playerBoard, opponentBoard, damage);
117
132
  return {
118
133
  result: 'won',
@@ -204,7 +219,8 @@ class Simulator {
204
219
  if (!this.gameState.applyDamageCap) {
205
220
  return damage;
206
221
  }
207
- const isDuos = !!((_a = this.gameState.gameState.player) === null || _a === void 0 ? void 0 : _a.teammate) || !!((_b = this.gameState.gameState.opponent) === null || _b === void 0 ? void 0 : _b.teammate);
222
+ const isDuos = !!((_a = this.gameState.gameState.playerInitial) === null || _a === void 0 ? void 0 : _a.teammate) ||
223
+ !!((_b = this.gameState.gameState.opponentInitial) === null || _b === void 0 ? void 0 : _b.teammate);
208
224
  return (0, damage_cap_1.applyCombatDamageCap)(damage, this.gameState.currentTurn, this.gameState.numberOfPlayersAlive, isDuos);
209
225
  }
210
226
  buildBoardTotalDamage(playerBoard, teammateBoard) {
@@ -1 +1 @@
1
- {"version":3,"file":"simulator.js","sourceRoot":"","sources":["../../src/simulation/simulator.ts"],"names":[],"mappings":"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","sourcesContent":["import { getEffectiveTechLevel } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { debugState } from '../debug-state';\r\nimport { SingleSimulationResult } from '../single-simulation-result';\r\nimport { stringifySimple, stringifySimpleCard } from '../utils';\r\nimport { simulateAttack } from './attack';\r\nimport { clearStealthIfNeeded } from './auras';\r\nimport { applyCombatDamageCap } from './damage-cap';\r\nimport { FullGameState, PlayerState } from './internal-game-state';\r\nimport { resolvePendingEffects } from './pending-effects';\r\nimport { handleStartOfCombat } from './start-of-combat/start-of-combat';\r\nimport { handleSummonsWhenSpace } from './summon-when-space';\r\n\r\n// New simulator should be instantiated for each match\r\nexport class Simulator {\r\n\tprivate currentAttacker: number;\r\n\tprivate currentSpeedAttacker = -1;\r\n\r\n\tprivate hasShowShortCircuitWarning = false;\r\n\r\n\t// It should come already initialized\r\n\tconstructor(private readonly gameState: FullGameState) {}\r\n\r\n\t// Here we suppose that the BoardEntity only contain at most the enchantments that are linked\r\n\t// to auras (so we probably should hand-filter that, since there are actually few auras)\r\n\tpublic simulateSingleBattle(playerState: PlayerState, opponentState: PlayerState): SingleSimulationResult {\r\n\t\tlet playerBoard: BoardEntity[] = playerState.board;\r\n\t\tlet playerEntity: BgsPlayerEntity = playerState.player;\r\n\t\tlet opponentBoard: BoardEntity[] = opponentState.board;\r\n\t\tlet opponentEntity: BgsPlayerEntity = opponentState.player;\r\n\r\n\t\tlet maxEntityId = -Infinity;\r\n\t\tfor (const group of [playerBoard, opponentBoard, playerEntity.hand, opponentEntity.hand]) {\r\n\t\t\tfor (const entity of group ?? []) {\r\n\t\t\t\tif (entity.entityId > maxEntityId) {\r\n\t\t\t\t\tmaxEntityId = entity.entityId;\r\n\t\t\t\t}\r\n\t\t\t\tfor (const enchantment of entity.enchantments ?? []) {\r\n\t\t\t\t\tif (enchantment.originEntityId > maxEntityId) {\r\n\t\t\t\t\t\tmaxEntityId = enchantment.originEntityId;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.gameState.sharedState.currentEntityId = maxEntityId + 1;\r\n\r\n\t\twhile (\r\n\t\t\t!playerEntity.startOfCombatDone ||\r\n\t\t\t!opponentEntity.startOfCombatDone ||\r\n\t\t\t(playerBoard?.length > 0 && opponentBoard?.length > 0)\r\n\t\t) {\r\n\t\t\t// Diagnostic only: detect runaway enchantment growth. The full entity id arrays are\r\n\t\t\t// only built in debug mode, since this allocates a lot on every battle pass\r\n\t\t\tif (debugState?.active) {\r\n\t\t\t\tthis.logRunawayEntityDiagnostics(playerBoard, playerEntity, opponentBoard, opponentEntity);\r\n\t\t\t}\r\n\t\t\tthis.simulateSingleBattlePass(playerBoard, playerEntity, opponentBoard, opponentEntity);\r\n\t\t\tif (this.hasShowShortCircuitWarning) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// The only case where there can only 0-attack minions on a board is when both boards\r\n\t\t\t// are that way (otherwise one side would kill the other)\r\n\t\t\tconst areBothBoards0Attack =\r\n\t\t\t\tplayerState.board.length > 0 &&\r\n\t\t\t\tplayerState.board.every((entity) => entity.attack === 0) &&\r\n\t\t\t\topponentState.board.length > 0 &&\r\n\t\t\t\topponentState.board.every((entity) => entity.attack === 0);\r\n\t\t\tif (areBothBoards0Attack) {\r\n\t\t\t\tplayerState.board = [];\r\n\t\t\t\topponentState.board = [];\r\n\t\t\t}\r\n\r\n\t\t\tconst isPlayerDefeated = playerState.board.length === 0 || playerState.player.hpLeft <= 0;\r\n\t\t\tconst isOpponentDefeated = opponentState.board.length === 0 || opponentState.player.hpLeft <= 0;\r\n\t\t\tif (isPlayerDefeated) {\r\n\t\t\t\tplayerBoard = playerState.teammate?.board;\r\n\t\t\t\tplayerState.board = [];\r\n\t\t\t\tplayerEntity = playerState.teammate?.player;\r\n\t\t\t} else {\r\n\t\t\t\tplayerBoard = playerState.board;\r\n\t\t\t\tplayerEntity = playerState.player;\r\n\t\t\t}\r\n\t\t\tif (isOpponentDefeated) {\r\n\t\t\t\topponentBoard = opponentState.teammate?.board;\r\n\t\t\t\topponentState.board = [];\r\n\t\t\t\topponentEntity = opponentState.teammate?.player;\r\n\t\t\t} else {\r\n\t\t\t\topponentBoard = opponentState.board;\r\n\t\t\t\topponentEntity = opponentState.player;\r\n\t\t\t}\r\n\t\t\t// So that gameState.player always refers to the active player\r\n\t\t\tif (isPlayerDefeated) {\r\n\t\t\t\t// Reset deaths\r\n\t\t\t\tthis.gameState.sharedState.deaths = this.gameState.sharedState.deaths.filter(\r\n\t\t\t\t\t(e) => e.friendly !== this.gameState.gameState.player.player.friendly,\r\n\t\t\t\t);\r\n\t\t\t\tthis.gameState.gameState.player.teammate = {\r\n\t\t\t\t\tboard: this.gameState.gameState.player.board,\r\n\t\t\t\t\tplayer: this.gameState.gameState.player.player,\r\n\t\t\t\t};\r\n\t\t\t\tthis.gameState.gameState.player.player = playerEntity;\r\n\t\t\t\tthis.gameState.gameState.player.board = playerBoard;\r\n\r\n\t\t\t\t// const initialPlayer = this.gameState.gameState.playerInitial;\r\n\t\t\t\t// const initialPlayerTeammate = initialPlayer.teammate;\r\n\t\t\t}\r\n\t\t\tif (isOpponentDefeated) {\r\n\t\t\t\t// Reset deaths\r\n\t\t\t\tthis.gameState.sharedState.deaths = this.gameState.sharedState.deaths.filter(\r\n\t\t\t\t\t(e) => e.friendly !== this.gameState.gameState.opponent.player.friendly,\r\n\t\t\t\t);\r\n\t\t\t\tthis.gameState.gameState.opponent.teammate = {\r\n\t\t\t\t\tboard: this.gameState.gameState.opponent.board,\r\n\t\t\t\t\tplayer: this.gameState.gameState.opponent.player,\r\n\t\t\t\t};\r\n\t\t\t\tthis.gameState.gameState.opponent.player = opponentEntity;\r\n\t\t\t\tthis.gameState.gameState.opponent.board = opponentBoard;\r\n\t\t\t}\r\n\r\n\t\t\tif (!playerEntity || !opponentEntity) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (\r\n\t\t\t(!playerBoard?.length && !opponentBoard?.length) ||\r\n\t\t\t// E.g. when both players have a 0-attack minion\r\n\t\t\t(playerBoard?.length > 0 && opponentBoard?.length > 0)\r\n\t\t) {\r\n\t\t\treturn {\r\n\t\t\t\tresult: 'tied',\r\n\t\t\t} as SingleSimulationResult;\r\n\t\t}\r\n\t\tif (!playerBoard?.length || playerEntity.hpLeft <= 0) {\r\n\t\t\tconst damage = this.capDamage(\r\n\t\t\t\tthis.buildBoardTotalDamage(opponentBoard, this.gameState.gameState.opponent?.teammate?.board) +\r\n\t\t\t\t\topponentEntity.tavernTier,\r\n\t\t\t);\r\n\t\t\tthis.gameState.spectator.registerOpponentAttack(playerBoard, opponentBoard, damage);\r\n\t\t\treturn {\r\n\t\t\t\tresult: 'lost',\r\n\t\t\t\tdamageDealt: damage,\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst damage = this.capDamage(\r\n\t\t\tthis.buildBoardTotalDamage(playerBoard, this.gameState.gameState.player?.teammate?.board) +\r\n\t\t\t\tplayerEntity.tavernTier,\r\n\t\t);\r\n\t\tthis.gameState.spectator.registerPlayerAttack(playerBoard, opponentBoard, damage);\r\n\t\treturn {\r\n\t\t\tresult: 'won',\r\n\t\t\tdamageDealt: damage,\r\n\t\t};\r\n\t}\r\n\r\n\tprivate logRunawayEntityDiagnostics(\r\n\t\tplayerBoard: BoardEntity[],\r\n\t\tplayerEntity: BgsPlayerEntity,\r\n\t\topponentBoard: BoardEntity[],\r\n\t\topponentEntity: BgsPlayerEntity,\r\n\t): void {\r\n\t\tconst allEntityIds: number[] = [];\r\n\t\tfor (const group of [playerBoard, opponentBoard, playerEntity.hand, opponentEntity.hand]) {\r\n\t\t\tfor (const entity of group ?? []) {\r\n\t\t\t\tconst result = [entity.entityId, ...(entity.enchantments?.map((e) => e.originEntityId) ?? [])];\r\n\t\t\t\tif (result.length > 200) {\r\n\t\t\t\t\tconsole.log(\r\n\t\t\t\t\t\t'too many entities for entity',\r\n\t\t\t\t\t\tresult.length,\r\n\t\t\t\t\t\tstringifySimpleCard(entity, this.gameState.allCards),\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\tallEntityIds.push(...result);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (allEntityIds.length > 10000) {\r\n\t\t\tconsole.log('allEntityIds2', allEntityIds, new Error().stack);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate simulateSingleBattlePass(\r\n\t\tplayerBoard: BoardEntity[],\r\n\t\tplayerEntity: BgsPlayerEntity,\r\n\t\topponentBoard: BoardEntity[],\r\n\t\topponentEntity: BgsPlayerEntity,\r\n\t) {\r\n\t\tif (debugState?.active) {\r\n\t\t\tdebugState.onBattleStart();\r\n\t\t}\r\n\t\t// Start of combat happens only once, so we need to flag whether it has already happened for a\r\n\t\t// given player\r\n\t\tthis.gameState.spectator.registerStartOfCombat(playerBoard, opponentBoard, playerEntity, opponentEntity);\r\n\r\n\t\t// Who attacks first is decided by the game before the hero power comes into effect. However, the full board (with the generated minion)\r\n\t\t// is sent tothe simulator\r\n\t\t// But in fact, the first player decision takes into account that additional minion. See\r\n\t\t// https://replays.firestoneapp.com/?reviewId=ddbbbe93-464b-4400-8e8d-4abca8680a2e\r\n\t\tconst effectivePlayerBoardLength = playerBoard.length;\r\n\t\tconst effectiveOpponentBoardLength = opponentBoard.length;\r\n\t\tthis.currentAttacker =\r\n\t\t\teffectivePlayerBoardLength > effectiveOpponentBoardLength\r\n\t\t\t\t? 0\r\n\t\t\t\t: effectiveOpponentBoardLength > effectivePlayerBoardLength\r\n\t\t\t\t? 1\r\n\t\t\t\t: Math.round(Math.random());\r\n\t\tconst suggestedNewCurrentAttacker = handleStartOfCombat(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tthis.currentAttacker,\r\n\t\t\tthis.gameState,\r\n\t\t);\r\n\t\tthis.currentAttacker = suggestedNewCurrentAttacker;\r\n\t\tlet counter = 0;\r\n\t\tif (debugState?.active) {\r\n\t\t\tthis.currentAttacker = debugState.forcedCurrentAttacker ?? this.currentAttacker;\r\n\t\t}\r\n\t\twhile (\r\n\t\t\tplayerBoard.length > 0 &&\r\n\t\t\topponentBoard.length > 0 &&\r\n\t\t\tplayerEntity.hpLeft > 0 &&\r\n\t\t\topponentEntity.hpLeft > 0\r\n\t\t) {\r\n\t\t\thandleSummonsWhenSpace(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\tclearStealthIfNeeded(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\t// console.log('this.currentSpeedAttacker', this.currentAttacker);\r\n\t\t\t// If there are \"attack immediately\" minions, we keep the same player\r\n\t\t\t// We put it here so that it can kick in after the start of combat effects. However here we don't want\r\n\t\t\t// to change who attacks first, so we repeat that block again after all the attacks have been resolved\r\n\t\t\t// FIXME: This is not strictly correct - if there are multiple attack immediately\r\n\t\t\t// minions that spawn on both player sides it might get a bit more complex\r\n\t\t\t// but overall it works\r\n\t\t\t// Also, this doesn't work when there are several deathrattle competing\r\n\t\t\t// to know who triggers first. See the second test case of the scallywag.test.ts\r\n\t\t\t// that is not handled properly today (the attack should in some cases happen before\r\n\t\t\t// the other deathrattle procs)\r\n\t\t\tif (playerBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 0;\r\n\t\t\t} else if (opponentBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 1;\r\n\t\t\t} else {\r\n\t\t\t\tthis.currentSpeedAttacker = -1;\r\n\t\t\t}\r\n\t\t\tif (\r\n\t\t\t\tplayerBoard.filter((e) => e.attack > 0).length === 0 &&\r\n\t\t\t\topponentBoard.filter((e) => e.attack > 0).length === 0\r\n\t\t\t) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// console.log('this.currentSpeedAttacker 2', this.currentAttacker, this.currentSpeedAttacker);\r\n\t\t\tif (this.currentSpeedAttacker === 0 || (this.currentSpeedAttacker === -1 && this.currentAttacker === 0)) {\r\n\t\t\t\tsimulateAttack(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\t} else {\r\n\t\t\t\tsimulateAttack(opponentBoard, opponentEntity, playerBoard, playerEntity, this.gameState);\r\n\t\t\t}\r\n\r\n\t\t\tresolvePendingEffects(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\t// Update the attacker indices in case there were some deaths\r\n\t\t\tif (playerBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 0;\r\n\t\t\t} else if (opponentBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 1;\r\n\t\t\t} else {\r\n\t\t\t\tthis.currentSpeedAttacker = -1;\r\n\t\t\t\tthis.currentAttacker = (this.currentAttacker + 1) % 2;\r\n\t\t\t}\r\n\t\t\tcounter++;\r\n\t\t\tif (counter > 400 && !this.hasShowShortCircuitWarning) {\r\n\t\t\t\tconsole.warn(\r\n\t\t\t\t\t'short-circuiting simulation, too many iterations',\r\n\t\t\t\t\tcounter,\r\n\t\t\t\t\t'\\n',\r\n\t\t\t\t\tstringifySimple(playerBoard, this.gameState.allCards),\r\n\t\t\t\t\t'\\n',\r\n\t\t\t\t\tstringifySimple(opponentBoard, this.gameState.allCards),\r\n\t\t\t\t);\r\n\t\t\t\tthis.hasShowShortCircuitWarning = true;\r\n\t\t\t\tbreak;\r\n\t\t\t\t// return null;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate capDamage(damage: number): number {\r\n\t\tif (!this.gameState.applyDamageCap) {\r\n\t\t\treturn damage;\r\n\t\t}\r\n\t\tconst isDuos =\r\n\t\t\t!!this.gameState.gameState.player?.teammate || !!this.gameState.gameState.opponent?.teammate;\r\n\t\treturn applyCombatDamageCap(\r\n\t\t\tdamage,\r\n\t\t\tthis.gameState.currentTurn,\r\n\t\t\tthis.gameState.numberOfPlayersAlive,\r\n\t\t\tisDuos,\r\n\t\t);\r\n\t}\r\n\r\n\tprivate buildBoardTotalDamage(playerBoard: readonly BoardEntity[], teammateBoard?: BoardEntity[]): number {\r\n\t\tconst damageFromPlayerBoard = playerBoard\r\n\t\t\t.map((entity) =>\r\n\t\t\t\tgetEffectiveTechLevel(this.gameState.allCards.getCard(entity.cardId), this.gameState.allCards),\r\n\t\t\t)\r\n\t\t\t.reduce((a, b) => a + b, 0);\r\n\t\tconst numberOfTeamateMinionsToSummnon = 7 - playerBoard.length;\r\n\t\tconst damageFromTeammateBoard =\r\n\t\t\tteammateBoard\r\n\t\t\t\t?.slice(0, numberOfTeamateMinionsToSummnon)\r\n\t\t\t\t.map((entity) =>\r\n\t\t\t\t\tgetEffectiveTechLevel(this.gameState.allCards.getCard(entity.cardId), this.gameState.allCards),\r\n\t\t\t\t)\r\n\t\t\t\t.reduce((a, b) => a + b, 0) ?? 0;\r\n\t\treturn damageFromPlayerBoard + damageFromTeammateBoard;\r\n\t}\r\n}\r\n"]}
1
+ {"version":3,"file":"simulator.js","sourceRoot":"","sources":["../../src/simulation/simulator.ts"],"names":[],"mappings":"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","sourcesContent":["import { getEffectiveTechLevel } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { debugState } from '../debug-state';\r\nimport { SingleSimulationResult } from '../single-simulation-result';\r\nimport { stringifySimple, stringifySimpleCard } from '../utils';\r\nimport { simulateAttack } from './attack';\r\nimport { clearStealthIfNeeded } from './auras';\r\nimport { applyCombatDamageCap } from './damage-cap';\r\nimport { FullGameState, PlayerState } from './internal-game-state';\r\nimport { resolvePendingEffects } from './pending-effects';\r\nimport { tryPreventCombatDamageWithIceBlock } from './secrets';\r\nimport { handleStartOfCombat } from './start-of-combat/start-of-combat';\r\nimport { handleSummonsWhenSpace } from './summon-when-space';\r\n\r\n// New simulator should be instantiated for each match\r\nexport class Simulator {\r\n\tprivate currentAttacker: number;\r\n\tprivate currentSpeedAttacker = -1;\r\n\r\n\tprivate hasShowShortCircuitWarning = false;\r\n\r\n\t// It should come already initialized\r\n\tconstructor(private readonly gameState: FullGameState) {}\r\n\r\n\t// Here we suppose that the BoardEntity only contain at most the enchantments that are linked\r\n\t// to auras (so we probably should hand-filter that, since there are actually few auras)\r\n\tpublic simulateSingleBattle(playerState: PlayerState, opponentState: PlayerState): SingleSimulationResult {\r\n\t\tlet playerBoard: BoardEntity[] = playerState.board;\r\n\t\tlet playerEntity: BgsPlayerEntity = playerState.player;\r\n\t\tlet opponentBoard: BoardEntity[] = opponentState.board;\r\n\t\tlet opponentEntity: BgsPlayerEntity = opponentState.player;\r\n\r\n\t\tlet maxEntityId = -Infinity;\r\n\t\tfor (const group of [playerBoard, opponentBoard, playerEntity.hand, opponentEntity.hand]) {\r\n\t\t\tfor (const entity of group ?? []) {\r\n\t\t\t\tif (entity.entityId > maxEntityId) {\r\n\t\t\t\t\tmaxEntityId = entity.entityId;\r\n\t\t\t\t}\r\n\t\t\t\tfor (const enchantment of entity.enchantments ?? []) {\r\n\t\t\t\t\tif (enchantment.originEntityId > maxEntityId) {\r\n\t\t\t\t\t\tmaxEntityId = enchantment.originEntityId;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.gameState.sharedState.currentEntityId = maxEntityId + 1;\r\n\r\n\t\twhile (\r\n\t\t\t!playerEntity.startOfCombatDone ||\r\n\t\t\t!opponentEntity.startOfCombatDone ||\r\n\t\t\t(playerBoard?.length > 0 && opponentBoard?.length > 0)\r\n\t\t) {\r\n\t\t\t// Diagnostic only: detect runaway enchantment growth. The full entity id arrays are\r\n\t\t\t// only built in debug mode, since this allocates a lot on every battle pass\r\n\t\t\tif (debugState?.active) {\r\n\t\t\t\tthis.logRunawayEntityDiagnostics(playerBoard, playerEntity, opponentBoard, opponentEntity);\r\n\t\t\t}\r\n\t\t\tthis.simulateSingleBattlePass(playerBoard, playerEntity, opponentBoard, opponentEntity);\r\n\t\t\tif (this.hasShowShortCircuitWarning) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// The only case where there can only 0-attack minions on a board is when both boards\r\n\t\t\t// are that way (otherwise one side would kill the other)\r\n\t\t\tconst areBothBoards0Attack =\r\n\t\t\t\tplayerState.board.length > 0 &&\r\n\t\t\t\tplayerState.board.every((entity) => entity.attack === 0) &&\r\n\t\t\t\topponentState.board.length > 0 &&\r\n\t\t\t\topponentState.board.every((entity) => entity.attack === 0);\r\n\t\t\tif (areBothBoards0Attack) {\r\n\t\t\t\tplayerState.board = [];\r\n\t\t\t\topponentState.board = [];\r\n\t\t\t}\r\n\r\n\t\t\tconst isPlayerDefeated = playerState.board.length === 0 || playerState.player.hpLeft <= 0;\r\n\t\t\tconst isOpponentDefeated = opponentState.board.length === 0 || opponentState.player.hpLeft <= 0;\r\n\t\t\tif (isPlayerDefeated) {\r\n\t\t\t\tplayerBoard = playerState.teammate?.board;\r\n\t\t\t\tplayerState.board = [];\r\n\t\t\t\tplayerEntity = playerState.teammate?.player;\r\n\t\t\t} else {\r\n\t\t\t\tplayerBoard = playerState.board;\r\n\t\t\t\tplayerEntity = playerState.player;\r\n\t\t\t}\r\n\t\t\tif (isOpponentDefeated) {\r\n\t\t\t\topponentBoard = opponentState.teammate?.board;\r\n\t\t\t\topponentState.board = [];\r\n\t\t\t\topponentEntity = opponentState.teammate?.player;\r\n\t\t\t} else {\r\n\t\t\t\topponentBoard = opponentState.board;\r\n\t\t\t\topponentEntity = opponentState.player;\r\n\t\t\t}\r\n\t\t\t// So that gameState.player always refers to the active player.\r\n\t\t\t// Only swap when a real Duos teammate takes over — assigning an empty\r\n\t\t\t// teammate shell on solo defeat made isDuos true and used the flat 15\r\n\t\t\t// damage cap instead of the turn-scaled solo cap (35dd5300 t4: 13→10).\r\n\t\t\tif (isPlayerDefeated && playerEntity) {\r\n\t\t\t\t// Reset deaths\r\n\t\t\t\tthis.gameState.sharedState.deaths = this.gameState.sharedState.deaths.filter(\r\n\t\t\t\t\t(e) => e.friendly !== this.gameState.gameState.player.player.friendly,\r\n\t\t\t\t);\r\n\t\t\t\tthis.gameState.gameState.player.teammate = {\r\n\t\t\t\t\tboard: this.gameState.gameState.player.board,\r\n\t\t\t\t\tplayer: this.gameState.gameState.player.player,\r\n\t\t\t\t};\r\n\t\t\t\tthis.gameState.gameState.player.player = playerEntity;\r\n\t\t\t\tthis.gameState.gameState.player.board = playerBoard;\r\n\r\n\t\t\t\t// const initialPlayer = this.gameState.gameState.playerInitial;\r\n\t\t\t\t// const initialPlayerTeammate = initialPlayer.teammate;\r\n\t\t\t}\r\n\t\t\tif (isOpponentDefeated && opponentEntity) {\r\n\t\t\t\t// Reset deaths\r\n\t\t\t\tthis.gameState.sharedState.deaths = this.gameState.sharedState.deaths.filter(\r\n\t\t\t\t\t(e) => e.friendly !== this.gameState.gameState.opponent.player.friendly,\r\n\t\t\t\t);\r\n\t\t\t\tthis.gameState.gameState.opponent.teammate = {\r\n\t\t\t\t\tboard: this.gameState.gameState.opponent.board,\r\n\t\t\t\t\tplayer: this.gameState.gameState.opponent.player,\r\n\t\t\t\t};\r\n\t\t\t\tthis.gameState.gameState.opponent.player = opponentEntity;\r\n\t\t\t\tthis.gameState.gameState.opponent.board = opponentBoard;\r\n\t\t\t}\r\n\r\n\t\t\tif (!playerEntity || !opponentEntity) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (\r\n\t\t\t(!playerBoard?.length && !opponentBoard?.length) ||\r\n\t\t\t// E.g. when both players have a 0-attack minion\r\n\t\t\t(playerBoard?.length > 0 && opponentBoard?.length > 0)\r\n\t\t) {\r\n\t\t\treturn {\r\n\t\t\t\tresult: 'tied',\r\n\t\t\t} as SingleSimulationResult;\r\n\t\t}\r\n\t\tif (!playerBoard?.length || playerEntity?.hpLeft <= 0) {\r\n\t\t\tconst winningHero = opponentEntity ?? opponentState.player;\r\n\t\t\tconst losingHero = playerEntity ?? playerState.player;\r\n\t\t\tlet damage = this.capDamage(\r\n\t\t\t\tthis.buildBoardTotalDamage(opponentBoard, this.gameState.gameState.opponent?.teammate?.board) +\r\n\t\t\t\t\t(winningHero?.tavernTier ?? 1),\r\n\t\t\t);\r\n\t\t\t// Full-game only: Ice Block prevents face damage (opt-in via applyIceBlock).\r\n\t\t\tif (\r\n\t\t\t\tthis.gameState.applyIceBlock &&\r\n\t\t\t\tdamage > 0 &&\r\n\t\t\t\ttryPreventCombatDamageWithIceBlock(losingHero)\r\n\t\t\t) {\r\n\t\t\t\tdamage = 0;\r\n\t\t\t}\r\n\t\t\tthis.gameState.spectator.registerOpponentAttack(playerBoard, opponentBoard, damage);\r\n\t\t\treturn {\r\n\t\t\t\tresult: 'lost',\r\n\t\t\t\tdamageDealt: damage,\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tconst winningHero = playerEntity ?? playerState.player;\r\n\t\tconst losingHero = opponentEntity ?? opponentState.player;\r\n\t\tlet damage = this.capDamage(\r\n\t\t\tthis.buildBoardTotalDamage(playerBoard, this.gameState.gameState.player?.teammate?.board) +\r\n\t\t\t\t(winningHero?.tavernTier ?? 1),\r\n\t\t);\r\n\t\tif (\r\n\t\t\tthis.gameState.applyIceBlock &&\r\n\t\t\tdamage > 0 &&\r\n\t\t\ttryPreventCombatDamageWithIceBlock(losingHero)\r\n\t\t) {\r\n\t\t\tdamage = 0;\r\n\t\t}\r\n\t\tthis.gameState.spectator.registerPlayerAttack(playerBoard, opponentBoard, damage);\r\n\t\treturn {\r\n\t\t\tresult: 'won',\r\n\t\t\tdamageDealt: damage,\r\n\t\t};\r\n\t}\r\n\r\n\tprivate logRunawayEntityDiagnostics(\r\n\t\tplayerBoard: BoardEntity[],\r\n\t\tplayerEntity: BgsPlayerEntity,\r\n\t\topponentBoard: BoardEntity[],\r\n\t\topponentEntity: BgsPlayerEntity,\r\n\t): void {\r\n\t\tconst allEntityIds: number[] = [];\r\n\t\tfor (const group of [playerBoard, opponentBoard, playerEntity.hand, opponentEntity.hand]) {\r\n\t\t\tfor (const entity of group ?? []) {\r\n\t\t\t\tconst result = [entity.entityId, ...(entity.enchantments?.map((e) => e.originEntityId) ?? [])];\r\n\t\t\t\tif (result.length > 200) {\r\n\t\t\t\t\tconsole.log(\r\n\t\t\t\t\t\t'too many entities for entity',\r\n\t\t\t\t\t\tresult.length,\r\n\t\t\t\t\t\tstringifySimpleCard(entity, this.gameState.allCards),\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\tallEntityIds.push(...result);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (allEntityIds.length > 10000) {\r\n\t\t\tconsole.log('allEntityIds2', allEntityIds, new Error().stack);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate simulateSingleBattlePass(\r\n\t\tplayerBoard: BoardEntity[],\r\n\t\tplayerEntity: BgsPlayerEntity,\r\n\t\topponentBoard: BoardEntity[],\r\n\t\topponentEntity: BgsPlayerEntity,\r\n\t) {\r\n\t\tif (debugState?.active) {\r\n\t\t\tdebugState.onBattleStart();\r\n\t\t}\r\n\t\t// Start of combat happens only once, so we need to flag whether it has already happened for a\r\n\t\t// given player\r\n\t\tthis.gameState.spectator.registerStartOfCombat(playerBoard, opponentBoard, playerEntity, opponentEntity);\r\n\r\n\t\t// Who attacks first is decided by the game before the hero power comes into effect. However, the full board (with the generated minion)\r\n\t\t// is sent tothe simulator\r\n\t\t// But in fact, the first player decision takes into account that additional minion. See\r\n\t\t// https://replays.firestoneapp.com/?reviewId=ddbbbe93-464b-4400-8e8d-4abca8680a2e\r\n\t\tconst effectivePlayerBoardLength = playerBoard.length;\r\n\t\tconst effectiveOpponentBoardLength = opponentBoard.length;\r\n\t\tthis.currentAttacker =\r\n\t\t\teffectivePlayerBoardLength > effectiveOpponentBoardLength\r\n\t\t\t\t? 0\r\n\t\t\t\t: effectiveOpponentBoardLength > effectivePlayerBoardLength\r\n\t\t\t\t? 1\r\n\t\t\t\t: Math.round(Math.random());\r\n\t\tconst suggestedNewCurrentAttacker = handleStartOfCombat(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tthis.currentAttacker,\r\n\t\t\tthis.gameState,\r\n\t\t);\r\n\t\tthis.currentAttacker = suggestedNewCurrentAttacker;\r\n\t\tlet counter = 0;\r\n\t\tif (debugState?.active) {\r\n\t\t\tthis.currentAttacker = debugState.forcedCurrentAttacker ?? this.currentAttacker;\r\n\t\t}\r\n\t\twhile (\r\n\t\t\tplayerBoard.length > 0 &&\r\n\t\t\topponentBoard.length > 0 &&\r\n\t\t\tplayerEntity.hpLeft > 0 &&\r\n\t\t\topponentEntity.hpLeft > 0\r\n\t\t) {\r\n\t\t\thandleSummonsWhenSpace(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\tclearStealthIfNeeded(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\t// console.log('this.currentSpeedAttacker', this.currentAttacker);\r\n\t\t\t// If there are \"attack immediately\" minions, we keep the same player\r\n\t\t\t// We put it here so that it can kick in after the start of combat effects. However here we don't want\r\n\t\t\t// to change who attacks first, so we repeat that block again after all the attacks have been resolved\r\n\t\t\t// FIXME: This is not strictly correct - if there are multiple attack immediately\r\n\t\t\t// minions that spawn on both player sides it might get a bit more complex\r\n\t\t\t// but overall it works\r\n\t\t\t// Also, this doesn't work when there are several deathrattle competing\r\n\t\t\t// to know who triggers first. See the second test case of the scallywag.test.ts\r\n\t\t\t// that is not handled properly today (the attack should in some cases happen before\r\n\t\t\t// the other deathrattle procs)\r\n\t\t\tif (playerBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 0;\r\n\t\t\t} else if (opponentBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 1;\r\n\t\t\t} else {\r\n\t\t\t\tthis.currentSpeedAttacker = -1;\r\n\t\t\t}\r\n\t\t\tif (\r\n\t\t\t\tplayerBoard.filter((e) => e.attack > 0).length === 0 &&\r\n\t\t\t\topponentBoard.filter((e) => e.attack > 0).length === 0\r\n\t\t\t) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// console.log('this.currentSpeedAttacker 2', this.currentAttacker, this.currentSpeedAttacker);\r\n\t\t\tif (this.currentSpeedAttacker === 0 || (this.currentSpeedAttacker === -1 && this.currentAttacker === 0)) {\r\n\t\t\t\tsimulateAttack(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\t} else {\r\n\t\t\t\tsimulateAttack(opponentBoard, opponentEntity, playerBoard, playerEntity, this.gameState);\r\n\t\t\t}\r\n\r\n\t\t\tresolvePendingEffects(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t\t// Update the attacker indices in case there were some deaths\r\n\t\t\tif (playerBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 0;\r\n\t\t\t} else if (opponentBoard.some((entity) => entity.attackImmediately)) {\r\n\t\t\t\tthis.currentSpeedAttacker = 1;\r\n\t\t\t} else {\r\n\t\t\t\tthis.currentSpeedAttacker = -1;\r\n\t\t\t\tthis.currentAttacker = (this.currentAttacker + 1) % 2;\r\n\t\t\t}\r\n\t\t\tcounter++;\r\n\t\t\tif (counter > 400 && !this.hasShowShortCircuitWarning) {\r\n\t\t\t\tconsole.warn(\r\n\t\t\t\t\t'short-circuiting simulation, too many iterations',\r\n\t\t\t\t\tcounter,\r\n\t\t\t\t\t'\\n',\r\n\t\t\t\t\tstringifySimple(playerBoard, this.gameState.allCards),\r\n\t\t\t\t\t'\\n',\r\n\t\t\t\t\tstringifySimple(opponentBoard, this.gameState.allCards),\r\n\t\t\t\t);\r\n\t\t\t\tthis.hasShowShortCircuitWarning = true;\r\n\t\t\t\tbreak;\r\n\t\t\t\t// return null;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tprivate capDamage(damage: number): number {\r\n\t\tif (!this.gameState.applyDamageCap) {\r\n\t\t\treturn damage;\r\n\t\t}\r\n\t\tconst isDuos =\r\n\t\t\t!!this.gameState.gameState.playerInitial?.teammate ||\r\n\t\t\t!!this.gameState.gameState.opponentInitial?.teammate;\r\n\t\treturn applyCombatDamageCap(\r\n\t\t\tdamage,\r\n\t\t\tthis.gameState.currentTurn,\r\n\t\t\tthis.gameState.numberOfPlayersAlive,\r\n\t\t\tisDuos,\r\n\t\t);\r\n\t}\r\n\r\n\tprivate buildBoardTotalDamage(playerBoard: readonly BoardEntity[], teammateBoard?: BoardEntity[]): number {\r\n\t\tconst damageFromPlayerBoard = playerBoard\r\n\t\t\t.map((entity) =>\r\n\t\t\t\tgetEffectiveTechLevel(this.gameState.allCards.getCard(entity.cardId), this.gameState.allCards),\r\n\t\t\t)\r\n\t\t\t.reduce((a, b) => a + b, 0);\r\n\t\tconst numberOfTeamateMinionsToSummnon = 7 - playerBoard.length;\r\n\t\tconst damageFromTeammateBoard =\r\n\t\t\tteammateBoard\r\n\t\t\t\t?.slice(0, numberOfTeamateMinionsToSummnon)\r\n\t\t\t\t.map((entity) =>\r\n\t\t\t\t\tgetEffectiveTechLevel(this.gameState.allCards.getCard(entity.cardId), this.gameState.allCards),\r\n\t\t\t\t)\r\n\t\t\t\t.reduce((a, b) => a + b, 0) ?? 0;\r\n\t\treturn damageFromPlayerBoard + damageFromTeammateBoard;\r\n\t}\r\n}\r\n"]}
@@ -13,6 +13,7 @@ const aim_left_1 = require("../../cards/impl/hero-power/aim-left");
13
13
  const aim_low_1 = require("../../cards/impl/hero-power/aim-low");
14
14
  const aim_right_1 = require("../../cards/impl/hero-power/aim-right");
15
15
  const all_will_burn_1 = require("../../cards/impl/hero-power/all-will-burn");
16
+ const avatar_of_nzoth_1 = require("../../cards/impl/hero-power/avatar-of-nzoth");
16
17
  const die_insects_1 = require("../../cards/impl/hero-power/die-insects");
17
18
  const earth_invocation_1 = require("../../cards/impl/hero-power/earth-invocation");
18
19
  const embrace_your_rage_1 = require("../../cards/impl/hero-power/embrace-your-rage");
@@ -153,6 +154,8 @@ const getStartOfCombatAction = (cardId) => {
153
154
  return lightning_invocation_1.LightningInvocation;
154
155
  case "TB_BaconShop_HP_061":
155
156
  return all_will_burn_1.AllWillBurn;
157
+ case "TB_BaconShop_HP_105":
158
+ return avatar_of_nzoth_1.AvatarOfNzoth;
156
159
  case "TB_BaconShop_HP_103":
157
160
  return embrace_your_rage_1.EmbraceYourRage;
158
161
  case "BG23_HERO_201p":
@@ -1 +1 @@
1
- {"version":3,"file":"soc-action-processor.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/soc-action-processor.ts"],"names":[],"mappings":";;;AAGA,+DAAsG;AACtG,oEAA+D;AAC/D,4EAAwE;AACxE,sFAAiF;AACjF,+EAA0E;AAC1E,iFAA6E;AAC7E,qEAAiE;AACjE,mEAA+D;AAC/D,mEAA+D;AAC/D,iEAA6D;AAC7D,qEAAiE;AACjE,6EAAwE;AACxE,yEAAqE;AACrE,mFAA+E;AAC/E,qFAAgF;AAChF,iFAA6E;AAC7E,mFAA8E;AAC9E,2FAAuF;AACvF,yEAAqE;AACrE,+EAA2E;AAC3E,qFAAiF;AACjF,2EAAuE;AACvE,uEAAoE;AACpE,mFAA+E;AAC/E,yEAAqE;AACrE,2EAAuE;AACvE,+EAA2E;AAC3E,yEAAqE;AACrE,mFAA+E;AAC/E,2EAAuE;AACvE,mFAA+E;AAC/E,uEAAmE;AACnE,yDAAsD;AACtD,uEAAmE;AACnE,qFAAgF;AAChF,2FAAsF;AACtF,yFAAoF;AACpF,uEAAmE;AACnE,6FAAwF;AACxF,2EAAuE;AACvE,0EAAsE;AACtE,gFAA4E;AAC5E,wFAAoF;AACpF,gFAA4E;AAC5E,0EAAsE;AACtE,oEAAgE;AAChE,wEAAoE;AACpE,8EAA0E;AAC1E,gFAA4E;AAC5E,oFAA+E;AAC/E,oFAAgF;AAChF,0EAAsE;AACtE,gFAA0E;AAC1E,gFAA4E;AAC5E,4EAAwE;AACxE,wFAAoF;AACpF,sFAAiF;AAEjF,sCAA+C;AAC/C,4DAA8D;AAGvD,MAAM,0BAA0B,GAAG,CACzC,MAAc,EACd,MAAkE,EAClE,KAAe,EACf,aAAsB,EACtB,MAA4B,EAClB,EAAE;IACZ,IAAI,YAAY,GAKT,KAAK,CAAC;IACb,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACrE,KAAK,IAAI,CAAC,GAAG,kBAAkB,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,MAAM,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,mBAAmB,MAAK,MAAM,EAAE;YACrD,OAAO,KAAK,CAAC;SACb;QAED,MAAM,MAAM,GAAG,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,CAAC;QACnC,IAAI,CAAC,CAAC,MAAM,EAAE;YACb,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAErC,wBAAwB,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;YACxD,IAAI,CAAC,CAAC,YAAY,EAAE;gBACnB,IAAI,aAAa,EAAE;oBAClB,IAAA,2BAAkB,EACjB,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EAIf,IAAI,CACJ,CAAC;oBAIF,MAAM,8BAA8B,GAAG,IAAA,0CAAsB,EAC5D,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;oBACF,IAAI,OAAO,YAAY,KAAK,SAAS,EAAE;wBACtC,YAAY,GAAG,YAAY,IAAI,8BAA8B,CAAC;qBAC9D;yBAAM;wBACN,YAAY,CAAC,8BAA8B;4BAC1C,YAAY,CAAC,8BAA8B,IAAI,8BAA8B,CAAC;qBAC/E;iBACD;gBACD,IAAI,OAAO,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,8BAA8B,EAAE;oBACrF,KAAK,CAAC,eAAe;wBACpB,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,MAAM;4BACpD,CAAC,CAAC,KAAK,CAAC,gBAAgB;gCACvB,CAAC,CAAC,CAAC;gCACH,CAAC,CAAC,CAAC;4BACJ,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM;gCACvD,CAAC,CAAC,KAAK,CAAC,gBAAgB;oCACvB,CAAC,CAAC,CAAC;oCACH,CAAC,CAAC,CAAC;gCACJ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;iBAC9B;aACD;SACD;KACD;IACD,OAAO,CAAC,CAAC,YAAY,CAAC;AACvB,CAAC,CAAC;AAvEW,QAAA,0BAA0B,8BAuErC;AAGF,MAAM,sBAAsB,GAAG,CAAC,MAAc,EAAqB,EAAE;IACpE,QAAQ,MAAM,EAAE;QAEf;YACC,OAAO,oBAAQ,CAAC;QACjB;YACC,OAAO,yCAAkB,CAAC;QAC3B;YACC,OAAO,wBAAU,CAAC;QAGnB;YACC,OAAO,0BAAW,CAAC;QACpB;YACC,OAAO,0CAAmB,CAAC;QAC5B,0BAAkD;QAClD;YACC,OAAO,uCAAiB,CAAC;QAC1B;YACC,OAAO,0CAAmB,CAAC;QAC5B;YACC,OAAO,kCAAe,CAAC;QACxB;YACC,OAAO,4BAAY,CAAC;QACrB;YACC,OAAO,sBAAS,CAAC;QAClB;YACC,OAAO,gCAAa,CAAC;QACtB;YACC,OAAO,kCAAe,CAAC;QACxB;YACC,OAAO,sCAAiB,CAAC;QAC1B;YACC,OAAO,8BAAa,CAAC;QACtB;YACC,OAAO,kCAAe,CAAC;QACxB;YACC,OAAO,gCAAc,CAAC;QACvB;YACC,OAAO,qCAAgB,CAAC;QAEzB;YACC,OAAO,4BAAY,CAAC;QACrB;YACC,OAAO,kCAAe,CAAC;QAGxB;YACC,OAAO,kCAAe,CAAC;QACxB;YACC,OAAO,kCAAe,CAAC;QACxB;YACC,OAAO,gCAAc,CAAC;QACvB;YACC,OAAO,0CAAmB,CAAC;QAC5B;YACC,OAAO,2BAAW,CAAC;QACpB;YACC,OAAO,mCAAe,CAAC;QACxB;YACC,OAAO,uBAAU,CAAC;QACnB;YACC,OAAO,0BAAW,CAAC;QACpB;YACC,OAAO,oCAAgB,CAAC;QACzB;YACC,OAAO,wBAAU,CAAC;QACnB;YACC,OAAO,wBAAU,CAAC;QACnB;YACC,OAAO,iCAAc,CAAC;QACvB;YACC,OAAO,8BAAa,CAAC;QACtB;YACC,OAAO,wBAAU,CAAC;QACnB;YACC,OAAO,kBAAO,CAAC;QAChB;YACC,OAAO,oBAAQ,CAAC;QACjB;YACC,OAAO,gBAAM,CAAC;QACf;YACC,OAAO,kBAAO,CAAC;QAGhB;YACC,OAAO,uCAAiB,CAAC;QAC1B;YACC,OAAO,8BAAa,CAAC;QACtB;YACC,OAAO,+BAAa,CAAC;QAGtB;YACC,OAAO,kCAAe,CAAC;QACxB;YACC,OAAO,sBAAS,CAAC;QAClB;YACC,OAAO,8BAAa,CAAC;QAGtB,gBAAoC;QACpC;YACC,OAAO,8BAAa,CAAC;QAItB,gBAAwC;QACxC;YACC,OAAO,sCAAiB,CAAC;QAC1B,gBAAkC;QAClC;YACC,OAAO,0BAAW,CAAC;QACpB,gBAAmC;QACnC;YACC,OAAO,4BAAY,CAAC;QACrB,gBAAwC;QACxC;YACC,OAAO,sCAAiB,CAAC;QAC1B,gBAAsC;QACtC;YACC,OAAO,kCAAe,CAAC;QACxB,gBAA2C;QAC3C;YACC,OAAO,6CAAoB,CAAC;QAC7B,gBAA0C;QAC1C;YACC,OAAO,2CAAmB,CAAC;QAI5B,gBAAwC;QACxC;YACC,OAAO,uCAAiB,CAAC;QAC1B,iBAA6B;QAC7B;YACC,OAAO,aAAK,CAAC;QACd,kCAAsD;QACtD;YACC,OAAO,8BAAa,CAAC;QACtB,gBAAkC;QAClC;YACC,OAAO,0BAAW,CAAC;QAEpB;YACC,MAAM,SAAS,GAAG,6BAAY,CAAC,MAAM,CAAC,CAAC;YACvC,IAAI,IAAA,iCAAgB,EAAC,SAAS,CAAC,EAAE;gBAChC,OAAO,SAAS,CAAC;aACjB;YACD,OAAO,IAAI,CAAC;KACb;AACF,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,SAAiB,EAAE,eAAuB,EAAE,YAA6B,EAAE,EAAE;IAE9G,MAAM,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAClD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAA6C,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CACpF,CAAC;IACF,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,KAAK,CAAC,IAAI,SAAS,GAAG,cAAc,CAAC,MAAM,EAAE;QACxF,OAAO;KACP;IAED,QAAQ,eAAe,EAAE;QACxB,uBAAwB;QACxB,0BAA2C;QAC3C,0BAAoD;QACpD,0BAAgD;QAChD,0BAAgD;QAChD,2BAA6B;QAC7B,2BAAyB;QACzB;YACC,OAAO;KACR;IAED,MAAM,aAAa,GAAG,cAAc,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACpD,aAAa,CAAC,cAAc,EAAE,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,YAA6B,EAAE,EAAE;IAC/D,OAAO,YAAY,CAAC,QAAQ,CAAC,MAAM,CAClC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAA6C,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CACpF,CAAC,MAAM,CAAC;AACV,CAAC,CAAC","sourcesContent":["import { BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\nimport { hasStartOfCombat, StartOfCombatCard, StartOfCombatTiming } from '../../cards/card.interface';\r\nimport { cardMappings } from '../../cards/impl/_card-mappings';\r\nimport { AnomalousTwin } from '../../cards/impl/anomaly/anomalous-twin';\r\nimport { BlessedOrBlighted } from '../../cards/impl/anomaly/blessed-or-blighted';\r\nimport { BoonOfBeetles } from '../../cards/impl/bg-spell/boon-of-beetles';\r\nimport { ToxicTumbleweed } from '../../cards/impl/bg-spell/toxic-tumbleweed';\r\nimport { UpperHand } from '../../cards/impl/bg-spell/upper-hand';\r\nimport { AimHigh } from '../../cards/impl/hero-power/aim-high';\r\nimport { AimLeft } from '../../cards/impl/hero-power/aim-left';\r\nimport { AimLow } from '../../cards/impl/hero-power/aim-low';\r\nimport { AimRight } from '../../cards/impl/hero-power/aim-right';\r\nimport { AllWillBurn } from '../../cards/impl/hero-power/all-will-burn';\r\nimport { DieInsects } from '../../cards/impl/hero-power/die-insects';\r\nimport { EarthInvocation } from '../../cards/impl/hero-power/earth-invocation';\r\nimport { EmbraceYourRage } from '../../cards/impl/hero-power/embrace-your-rage';\r\nimport { FireInvocation } from '../../cards/impl/hero-power/fire-invocation';\r\nimport { FireTheCannons } from '../../cards/impl/hero-power/fire-the-cannons';\r\nimport { LightningInvocation } from '../../cards/impl/hero-power/lightning-invocation';\r\nimport { MurlocKing } from '../../cards/impl/hero-power/murloc-king';\r\nimport { NefariousFire } from '../../cards/impl/hero-power/nefarious-fire';\r\nimport { RapidReanimation } from '../../cards/impl/hero-power/rapid-reanimation';\r\nimport { RebornRites } from '../../cards/impl/hero-power/reborn-rites';\r\nimport { Tentacular } from '../../cards/impl/hero-power/tentacular';\r\nimport { WaterInvocation } from '../../cards/impl/hero-power/water-invocation';\r\nimport { WaxWarband } from '../../cards/impl/hero-power/wax-warband';\r\nimport { AmberGuardian } from '../../cards/impl/minion/amber-guardian';\r\nimport { AudaciousAnchor } from '../../cards/impl/minion/audacious-anchor';\r\nimport { CarbonicCopy } from '../../cards/impl/minion/carbonic-copy';\r\nimport { CorruptedMyrmidon } from '../../cards/impl/minion/corrupted-myrmidon';\r\nimport { ElderTaggawag } from '../../cards/impl/minion/elder-taggawag';\r\nimport { HawkstriderHerald } from '../../cards/impl/minion/hawkstrider-herald';\r\nimport { MantidQueen } from '../../cards/impl/minion/mantid-queen';\r\nimport { Sandy } from '../../cards/impl/minion/sandy';\r\nimport { SunScreener } from '../../cards/impl/minion/sun-screener';\r\nimport { TheUninvitedGuest } from '../../cards/impl/minion/the-uninvited-guest';\r\nimport { ThousandthPaperDrake } from '../../cards/impl/minion/thousandth-paper-drake';\r\nimport { YulonFortuneGranter } from '../../cards/impl/minion/yulon-fortune-granter';\r\nimport { EvilTwin } from '../../cards/impl/quest-reward/evil-twin';\r\nimport { StaffOfOrigination } from '../../cards/impl/quest-reward/staff-of-origination';\r\nimport { StolenGold } from '../../cards/impl/quest-reward/stolen-gold';\r\nimport { FleetingVigor } from '../../cards/impl/spell/fleeting-vigor';\r\nimport { BronzeTimepiece } from '../../cards/impl/trinket/bronze-timepiece';\r\nimport { EmeraldDreamcatcher } from '../../cards/impl/trinket/emerald-dreamcatcher';\r\nimport { EternalPortrait } from '../../cards/impl/trinket/eternal-portrait';\r\nimport { FishySticker } from '../../cards/impl/trinket/fishy-sticker';\r\nimport { HoggyBank } from '../../cards/impl/trinket/hoggy-bank';\r\nimport { HollyMallet } from '../../cards/impl/trinket/holly-mallet';\r\nimport { IronforgeAnvil } from '../../cards/impl/trinket/ironforge-anvil';\r\nimport { JarredFrostling } from '../../cards/impl/trinket/jarred-frostling';\r\nimport { KarazhanChessSet } from '../../cards/impl/trinket/karazhan-chess-set';\r\nimport { RivendarePortrait } from '../../cards/impl/trinket/rivendare-portrait';\r\nimport { RustyTrident } from '../../cards/impl/trinket/rusty-trident';\r\nimport { ShipInABottle } from '../../cards/impl/trinket/ship-in-a-bottle';\r\nimport { SummoningSphere } from '../../cards/impl/trinket/summoning-sphere';\r\nimport { TinyfinOnesie } from '../../cards/impl/trinket/tinyfin-onesie';\r\nimport { TrainingCertificate } from '../../cards/impl/trinket/training-certificate';\r\nimport { ValorousMedallion } from '../../cards/impl/trinket/valorous-medaillion';\r\nimport { CardIds } from '../../services/card-ids';\r\nimport { processMinionDeath } from '../attack';\r\nimport { handleSummonsWhenSpace } from '../summon-when-space';\r\nimport { SoCInput } from './start-of-combat-input';\r\n\r\nexport const performStartOfCombatAction = (\r\n\tcardId: string,\r\n\tentity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\tinput: SoCInput,\r\n\tprocessDeaths: boolean,\r\n\ttiming?: StartOfCombatTiming,\r\n): boolean => {\r\n\tlet hasTriggered:\r\n\t\t| boolean\r\n\t\t| {\r\n\t\t\t\thasTriggered: boolean;\r\n\t\t\t\tshouldRecomputeCurrentAttacker: boolean;\r\n\t\t } = false;\r\n\tconst promoPortraitCount = getPromoPortraitCount(input.playerEntity);\r\n\tfor (let i = promoPortraitCount; i >= 0; i--) {\r\n\t\tconst card = getStartOfCombatAction(cardId);\r\n\t\tif (!!timing && card?.startOfCombatTiming !== timing) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst action = card?.startOfCombat;\r\n\t\tif (!!action) {\r\n\t\t\thasTriggered = action(entity, input);\r\n\t\t\t// Always proc it (for promo portrait), and use the hasTriggered for finer control\r\n\t\t\tonStartOfCombatTriggered(i, cardId, input.playerEntity);\r\n\t\t\tif (!!hasTriggered) {\r\n\t\t\t\tif (processDeaths) {\r\n\t\t\t\t\tprocessMinionDeath(\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.opponentBoard,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=2eacbbc2-7dfa-487b-951d-0fa6d31d175e&turn=25&action=1\r\n\t\t\t\t\t\t// It looks like it doesn't look for the \"summons when space\" between Stitched Salvager's SoC and\r\n\t\t\t\t\t\t// Hawkstrider Herald SoC\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t);\r\n\t\t\t\t\t// https://replays.firestoneapp.com/?reviewId=6293597f-28fa-472e-ba8c-35f6b7deef58&turn=31&action=6\r\n\t\t\t\t\t// The first RapidReanimation triggers, resummons the target, then the second RapidReanimation triggers\r\n\t\t\t\t\t// So we need to process the resummon as soon as the minion dies, and before processing the second RapidReanimation\r\n\t\t\t\t\tconst shouldRecomputeCurrentAttacker = handleSummonsWhenSpace(\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.opponentBoard,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (typeof hasTriggered === 'boolean') {\r\n\t\t\t\t\t\thasTriggered = hasTriggered || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker =\r\n\t\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (typeof hasTriggered !== 'boolean' && hasTriggered.shouldRecomputeCurrentAttacker) {\r\n\t\t\t\t\tinput.currentAttacker =\r\n\t\t\t\t\t\tinput.playerBoard.length > input.opponentBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 0\r\n\t\t\t\t\t\t\t\t: 1\r\n\t\t\t\t\t\t\t: input.opponentBoard.length > input.playerBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 1\r\n\t\t\t\t\t\t\t\t: 0\r\n\t\t\t\t\t\t\t: Math.round(Math.random());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn !!hasTriggered;\r\n};\r\n\r\n// TODO: load all cards on start, then do some programmatic mapping\r\nconst getStartOfCombatAction = (cardId: string): StartOfCombatCard => {\r\n\tswitch (cardId) {\r\n\t\t// Quest rewards\r\n\t\tcase CardIds.EvilTwin:\r\n\t\t\treturn EvilTwin;\r\n\t\tcase CardIds.StaffOfOrigination_BG24_Reward_312:\r\n\t\t\treturn StaffOfOrigination;\r\n\t\tcase CardIds.StolenGold:\r\n\t\t\treturn StolenGold;\r\n\r\n\t\t// Trinkets\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\t\treturn HollyMallet;\r\n\t\tcase CardIds.TrainingCertificate_BG30_MagicItem_962:\r\n\t\t\treturn TrainingCertificate;\r\n\t\tcase CardIds.ValorousMedallion_BG30_MagicItem_970:\r\n\t\tcase CardIds.ValorousMedallion_ValorousMedallionToken_BG30_MagicItem_970t:\r\n\t\t\treturn ValorousMedallion;\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\t\treturn EmeraldDreamcatcher;\r\n\t\tcase CardIds.JarredFrostling_BG30_MagicItem_952:\r\n\t\t\treturn JarredFrostling;\r\n\t\tcase CardIds.RustyTrident_BG30_MagicItem_917:\r\n\t\t\treturn RustyTrident;\r\n\t\tcase CardIds.HoggyBank_BG30_MagicItem_411:\r\n\t\t\treturn HoggyBank;\r\n\t\tcase CardIds.ShipInABottle_BG30_MagicItem_407:\r\n\t\t\treturn ShipInABottle;\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\t\treturn EternalPortrait;\r\n\t\tcase CardIds.RivendarePortrait_BG30_MagicItem_310:\r\n\t\t\treturn RivendarePortrait;\r\n\t\tcase CardIds.TinyfinOnesie_BG30_MagicItem_441:\r\n\t\t\treturn TinyfinOnesie;\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\t\treturn BronzeTimepiece;\r\n\t\tcase CardIds.IronforgeAnvil_BG30_MagicItem_403:\r\n\t\t\treturn IronforgeAnvil;\r\n\t\tcase CardIds.KarazhanChessSet_BG30_MagicItem_972:\r\n\t\t\treturn KarazhanChessSet;\r\n\t\t// case CardIds.FishySticker_BG30_MagicItem_821:\r\n\t\tcase CardIds.FishySticker_FishyStickerToken_BG30_MagicItem_821t2:\r\n\t\t\treturn FishySticker;\r\n\t\tcase CardIds.SummoningSphere_BGDUO_MagicItem_003:\r\n\t\t\treturn SummoningSphere;\r\n\r\n\t\t// Hero powers\r\n\t\tcase CardIds.EarthInvocationToken:\r\n\t\t\treturn EarthInvocation;\r\n\t\tcase CardIds.WaterInvocationToken:\r\n\t\t\treturn WaterInvocation;\r\n\t\tcase CardIds.FireInvocationToken:\r\n\t\t\treturn FireInvocation;\r\n\t\tcase CardIds.LightningInvocationToken:\r\n\t\t\treturn LightningInvocation;\r\n\t\tcase CardIds.AllWillBurn:\r\n\t\t\treturn AllWillBurn;\r\n\t\tcase CardIds.EmbraceYourRage:\r\n\t\t\treturn EmbraceYourRage;\r\n\t\tcase CardIds.Ozumat_Tentacular:\r\n\t\t\treturn Tentacular;\r\n\t\tcase CardIds.RebornRites:\r\n\t\t\treturn RebornRites;\r\n\t\tcase CardIds.TeronGorefiend_RapidReanimation:\r\n\t\t\treturn RapidReanimation;\r\n\t\tcase CardIds.WaxWarband:\r\n\t\t\treturn WaxWarband;\r\n\t\tcase CardIds.DieInsects_TB_BaconShop_HP_019:\r\n\t\t\treturn DieInsects;\r\n\t\tcase CardIds.FireTheCannons:\r\n\t\t\treturn FireTheCannons;\r\n\t\tcase CardIds.NefariousFire:\r\n\t\t\treturn NefariousFire;\r\n\t\tcase CardIds.MurlocKing:\r\n\t\t\treturn MurlocKing;\r\n\t\tcase CardIds.AimLeftToken:\r\n\t\t\treturn AimLeft;\r\n\t\tcase CardIds.AimRightToken:\r\n\t\t\treturn AimRight;\r\n\t\tcase CardIds.AimLowToken:\r\n\t\t\treturn AimLow;\r\n\t\tcase CardIds.AimHighToken:\r\n\t\t\treturn AimHigh;\r\n\r\n\t\t// Anomalies\r\n\t\tcase CardIds.BlessedOrBlighted_BG27_Anomaly_726:\r\n\t\t\treturn BlessedOrBlighted;\r\n\t\tcase CardIds.AnomalousTwin_BG27_Anomaly_560:\r\n\t\t\treturn AnomalousTwin;\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn BoonOfBeetles;\r\n\r\n\t\t// Spells\r\n\t\tcase CardIds.ToxicTumbleweed_BG28_641:\r\n\t\t\treturn ToxicTumbleweed;\r\n\t\tcase CardIds.UpperHand_BG28_573:\r\n\t\t\treturn UpperHand;\r\n\t\tcase CardIds.FleetingVigor_BG28_519:\r\n\t\t\treturn FleetingVigor;\r\n\r\n\t\t// Minions\r\n\t\tcase CardIds.AmberGuardian_BG24_500:\r\n\t\tcase CardIds.AmberGuardian_BG24_500_G:\r\n\t\t\treturn AmberGuardian;\r\n\t\t// case CardIds.SanctumRester_BG26_356:\r\n\t\t// case CardIds.SanctumRester_BG26_356_G:\r\n\t\t// \treturn SanctumRester;\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012:\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012_G:\r\n\t\t\treturn CorruptedMyrmidon;\r\n\t\tcase CardIds.MantidQueen_BG22_402:\r\n\t\tcase CardIds.MantidQueen_BG22_402_G:\r\n\t\t\treturn MantidQueen;\r\n\t\tcase CardIds.CarbonicCopy_BG27_503:\r\n\t\tcase CardIds.CarbonicCopy_BG27_503_G:\r\n\t\t\treturn CarbonicCopy;\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079:\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079_G:\r\n\t\t\treturn HawkstriderHerald;\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904:\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904_G:\r\n\t\t\treturn AudaciousAnchor;\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810:\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810_G:\r\n\t\t\treturn ThousandthPaperDrake;\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811:\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811_G:\r\n\t\t\treturn YulonFortuneGranter;\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872:\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872_G:\r\n\t\t// \treturn HoardingHatespawn;\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875:\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875_G:\r\n\t\t\treturn TheUninvitedGuest;\r\n\t\tcase CardIds.Sandy_BGDUO_125:\r\n\t\tcase CardIds.Sandy_BGDUO_125_G:\r\n\t\t\treturn Sandy;\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy:\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy_G:\r\n\t\t\treturn ElderTaggawag;\r\n\t\tcase CardIds.SunScreener_BG30_101:\r\n\t\tcase CardIds.SunScreener_BG30_101_G:\r\n\t\t\treturn SunScreener;\r\n\r\n\t\tdefault:\r\n\t\t\tconst candidate = cardMappings[cardId];\r\n\t\t\tif (hasStartOfCombat(candidate)) {\r\n\t\t\t\treturn candidate;\r\n\t\t\t}\r\n\t\t\treturn null;\r\n\t}\r\n};\r\n\r\nconst onStartOfCombatTriggered = (iteration: number, triggeredCardId: string, playerEntity: BgsPlayerEntity) => {\r\n\t// Some procs are iso-functional, and don't update the promo portrait\r\n\tconst promoPortraits = playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t);\r\n\tif (promoPortraits.length === 0 || iteration === 0 || iteration > promoPortraits.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tswitch (triggeredCardId) {\r\n\t\tcase CardIds.StolenGold:\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\tcase CardIds.SwattingInsects:\r\n\t\tcase CardIds.RebornRites:\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn;\r\n\t}\r\n\r\n\tconst promoPortrait = promoPortraits[iteration - 1];\r\n\tpromoPortrait.scriptDataNum1--;\r\n};\r\n\r\nconst getPromoPortraitCount = (playerEntity: BgsPlayerEntity) => {\r\n\treturn playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t).length;\r\n};\r\n"]}
1
+ {"version":3,"file":"soc-action-processor.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/soc-action-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\nimport { hasStartOfCombat, StartOfCombatCard, StartOfCombatTiming } from '../../cards/card.interface';\r\nimport { cardMappings } from '../../cards/impl/_card-mappings';\r\nimport { AnomalousTwin } from '../../cards/impl/anomaly/anomalous-twin';\r\nimport { BlessedOrBlighted } from '../../cards/impl/anomaly/blessed-or-blighted';\r\nimport { BoonOfBeetles } from '../../cards/impl/bg-spell/boon-of-beetles';\r\nimport { ToxicTumbleweed } from '../../cards/impl/bg-spell/toxic-tumbleweed';\r\nimport { UpperHand } from '../../cards/impl/bg-spell/upper-hand';\r\nimport { AimHigh } from '../../cards/impl/hero-power/aim-high';\r\nimport { AimLeft } from '../../cards/impl/hero-power/aim-left';\r\nimport { AimLow } from '../../cards/impl/hero-power/aim-low';\r\nimport { AimRight } from '../../cards/impl/hero-power/aim-right';\r\nimport { AllWillBurn } from '../../cards/impl/hero-power/all-will-burn';\r\nimport { AvatarOfNzoth } from '../../cards/impl/hero-power/avatar-of-nzoth';\r\nimport { DieInsects } from '../../cards/impl/hero-power/die-insects';\r\nimport { EarthInvocation } from '../../cards/impl/hero-power/earth-invocation';\r\nimport { EmbraceYourRage } from '../../cards/impl/hero-power/embrace-your-rage';\r\nimport { FireInvocation } from '../../cards/impl/hero-power/fire-invocation';\r\nimport { FireTheCannons } from '../../cards/impl/hero-power/fire-the-cannons';\r\nimport { LightningInvocation } from '../../cards/impl/hero-power/lightning-invocation';\r\nimport { MurlocKing } from '../../cards/impl/hero-power/murloc-king';\r\nimport { NefariousFire } from '../../cards/impl/hero-power/nefarious-fire';\r\nimport { RapidReanimation } from '../../cards/impl/hero-power/rapid-reanimation';\r\nimport { RebornRites } from '../../cards/impl/hero-power/reborn-rites';\r\nimport { Tentacular } from '../../cards/impl/hero-power/tentacular';\r\nimport { WaterInvocation } from '../../cards/impl/hero-power/water-invocation';\r\nimport { WaxWarband } from '../../cards/impl/hero-power/wax-warband';\r\nimport { AmberGuardian } from '../../cards/impl/minion/amber-guardian';\r\nimport { AudaciousAnchor } from '../../cards/impl/minion/audacious-anchor';\r\nimport { CarbonicCopy } from '../../cards/impl/minion/carbonic-copy';\r\nimport { CorruptedMyrmidon } from '../../cards/impl/minion/corrupted-myrmidon';\r\nimport { ElderTaggawag } from '../../cards/impl/minion/elder-taggawag';\r\nimport { HawkstriderHerald } from '../../cards/impl/minion/hawkstrider-herald';\r\nimport { MantidQueen } from '../../cards/impl/minion/mantid-queen';\r\nimport { Sandy } from '../../cards/impl/minion/sandy';\r\nimport { SunScreener } from '../../cards/impl/minion/sun-screener';\r\nimport { TheUninvitedGuest } from '../../cards/impl/minion/the-uninvited-guest';\r\nimport { ThousandthPaperDrake } from '../../cards/impl/minion/thousandth-paper-drake';\r\nimport { YulonFortuneGranter } from '../../cards/impl/minion/yulon-fortune-granter';\r\nimport { EvilTwin } from '../../cards/impl/quest-reward/evil-twin';\r\nimport { StaffOfOrigination } from '../../cards/impl/quest-reward/staff-of-origination';\r\nimport { StolenGold } from '../../cards/impl/quest-reward/stolen-gold';\r\nimport { FleetingVigor } from '../../cards/impl/spell/fleeting-vigor';\r\nimport { BronzeTimepiece } from '../../cards/impl/trinket/bronze-timepiece';\r\nimport { EmeraldDreamcatcher } from '../../cards/impl/trinket/emerald-dreamcatcher';\r\nimport { EternalPortrait } from '../../cards/impl/trinket/eternal-portrait';\r\nimport { FishySticker } from '../../cards/impl/trinket/fishy-sticker';\r\nimport { HoggyBank } from '../../cards/impl/trinket/hoggy-bank';\r\nimport { HollyMallet } from '../../cards/impl/trinket/holly-mallet';\r\nimport { IronforgeAnvil } from '../../cards/impl/trinket/ironforge-anvil';\r\nimport { JarredFrostling } from '../../cards/impl/trinket/jarred-frostling';\r\nimport { KarazhanChessSet } from '../../cards/impl/trinket/karazhan-chess-set';\r\nimport { RivendarePortrait } from '../../cards/impl/trinket/rivendare-portrait';\r\nimport { RustyTrident } from '../../cards/impl/trinket/rusty-trident';\r\nimport { ShipInABottle } from '../../cards/impl/trinket/ship-in-a-bottle';\r\nimport { SummoningSphere } from '../../cards/impl/trinket/summoning-sphere';\r\nimport { TinyfinOnesie } from '../../cards/impl/trinket/tinyfin-onesie';\r\nimport { TrainingCertificate } from '../../cards/impl/trinket/training-certificate';\r\nimport { ValorousMedallion } from '../../cards/impl/trinket/valorous-medaillion';\r\nimport { CardIds } from '../../services/card-ids';\r\nimport { processMinionDeath } from '../attack';\r\nimport { handleSummonsWhenSpace } from '../summon-when-space';\r\nimport { SoCInput } from './start-of-combat-input';\r\n\r\nexport const performStartOfCombatAction = (\r\n\tcardId: string,\r\n\tentity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\tinput: SoCInput,\r\n\tprocessDeaths: boolean,\r\n\ttiming?: StartOfCombatTiming,\r\n): boolean => {\r\n\tlet hasTriggered:\r\n\t\t| boolean\r\n\t\t| {\r\n\t\t\t\thasTriggered: boolean;\r\n\t\t\t\tshouldRecomputeCurrentAttacker: boolean;\r\n\t\t } = false;\r\n\tconst promoPortraitCount = getPromoPortraitCount(input.playerEntity);\r\n\tfor (let i = promoPortraitCount; i >= 0; i--) {\r\n\t\tconst card = getStartOfCombatAction(cardId);\r\n\t\tif (!!timing && card?.startOfCombatTiming !== timing) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst action = card?.startOfCombat;\r\n\t\tif (!!action) {\r\n\t\t\thasTriggered = action(entity, input);\r\n\t\t\t// Always proc it (for promo portrait), and use the hasTriggered for finer control\r\n\t\t\tonStartOfCombatTriggered(i, cardId, input.playerEntity);\r\n\t\t\tif (!!hasTriggered) {\r\n\t\t\t\tif (processDeaths) {\r\n\t\t\t\t\tprocessMinionDeath(\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.opponentBoard,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=2eacbbc2-7dfa-487b-951d-0fa6d31d175e&turn=25&action=1\r\n\t\t\t\t\t\t// It looks like it doesn't look for the \"summons when space\" between Stitched Salvager's SoC and\r\n\t\t\t\t\t\t// Hawkstrider Herald SoC\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t);\r\n\t\t\t\t\t// https://replays.firestoneapp.com/?reviewId=6293597f-28fa-472e-ba8c-35f6b7deef58&turn=31&action=6\r\n\t\t\t\t\t// The first RapidReanimation triggers, resummons the target, then the second RapidReanimation triggers\r\n\t\t\t\t\t// So we need to process the resummon as soon as the minion dies, and before processing the second RapidReanimation\r\n\t\t\t\t\tconst shouldRecomputeCurrentAttacker = handleSummonsWhenSpace(\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.opponentBoard,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (typeof hasTriggered === 'boolean') {\r\n\t\t\t\t\t\thasTriggered = hasTriggered || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker =\r\n\t\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (typeof hasTriggered !== 'boolean' && hasTriggered.shouldRecomputeCurrentAttacker) {\r\n\t\t\t\t\tinput.currentAttacker =\r\n\t\t\t\t\t\tinput.playerBoard.length > input.opponentBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 0\r\n\t\t\t\t\t\t\t\t: 1\r\n\t\t\t\t\t\t\t: input.opponentBoard.length > input.playerBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 1\r\n\t\t\t\t\t\t\t\t: 0\r\n\t\t\t\t\t\t\t: Math.round(Math.random());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn !!hasTriggered;\r\n};\r\n\r\n// TODO: load all cards on start, then do some programmatic mapping\r\nconst getStartOfCombatAction = (cardId: string): StartOfCombatCard => {\r\n\tswitch (cardId) {\r\n\t\t// Quest rewards\r\n\t\tcase CardIds.EvilTwin:\r\n\t\t\treturn EvilTwin;\r\n\t\tcase CardIds.StaffOfOrigination_BG24_Reward_312:\r\n\t\t\treturn StaffOfOrigination;\r\n\t\tcase CardIds.StolenGold:\r\n\t\t\treturn StolenGold;\r\n\r\n\t\t// Trinkets\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\t\treturn HollyMallet;\r\n\t\tcase CardIds.TrainingCertificate_BG30_MagicItem_962:\r\n\t\t\treturn TrainingCertificate;\r\n\t\tcase CardIds.ValorousMedallion_BG30_MagicItem_970:\r\n\t\tcase CardIds.ValorousMedallion_ValorousMedallionToken_BG30_MagicItem_970t:\r\n\t\t\treturn ValorousMedallion;\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\t\treturn EmeraldDreamcatcher;\r\n\t\tcase CardIds.JarredFrostling_BG30_MagicItem_952:\r\n\t\t\treturn JarredFrostling;\r\n\t\tcase CardIds.RustyTrident_BG30_MagicItem_917:\r\n\t\t\treturn RustyTrident;\r\n\t\tcase CardIds.HoggyBank_BG30_MagicItem_411:\r\n\t\t\treturn HoggyBank;\r\n\t\tcase CardIds.ShipInABottle_BG30_MagicItem_407:\r\n\t\t\treturn ShipInABottle;\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\t\treturn EternalPortrait;\r\n\t\tcase CardIds.RivendarePortrait_BG30_MagicItem_310:\r\n\t\t\treturn RivendarePortrait;\r\n\t\tcase CardIds.TinyfinOnesie_BG30_MagicItem_441:\r\n\t\t\treturn TinyfinOnesie;\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\t\treturn BronzeTimepiece;\r\n\t\tcase CardIds.IronforgeAnvil_BG30_MagicItem_403:\r\n\t\t\treturn IronforgeAnvil;\r\n\t\tcase CardIds.KarazhanChessSet_BG30_MagicItem_972:\r\n\t\t\treturn KarazhanChessSet;\r\n\t\t// case CardIds.FishySticker_BG30_MagicItem_821:\r\n\t\tcase CardIds.FishySticker_FishyStickerToken_BG30_MagicItem_821t2:\r\n\t\t\treturn FishySticker;\r\n\t\tcase CardIds.SummoningSphere_BGDUO_MagicItem_003:\r\n\t\t\treturn SummoningSphere;\r\n\r\n\t\t// Hero powers\r\n\t\tcase CardIds.EarthInvocationToken:\r\n\t\t\treturn EarthInvocation;\r\n\t\tcase CardIds.WaterInvocationToken:\r\n\t\t\treturn WaterInvocation;\r\n\t\tcase CardIds.FireInvocationToken:\r\n\t\t\treturn FireInvocation;\r\n\t\tcase CardIds.LightningInvocationToken:\r\n\t\t\treturn LightningInvocation;\r\n\t\tcase CardIds.AllWillBurn:\r\n\t\t\treturn AllWillBurn;\r\n\t\tcase CardIds.AvatarOfNzoth:\r\n\t\t\treturn AvatarOfNzoth;\r\n\t\tcase CardIds.EmbraceYourRage:\r\n\t\t\treturn EmbraceYourRage;\r\n\t\tcase CardIds.Ozumat_Tentacular:\r\n\t\t\treturn Tentacular;\r\n\t\tcase CardIds.RebornRites:\r\n\t\t\treturn RebornRites;\r\n\t\tcase CardIds.TeronGorefiend_RapidReanimation:\r\n\t\t\treturn RapidReanimation;\r\n\t\tcase CardIds.WaxWarband:\r\n\t\t\treturn WaxWarband;\r\n\t\tcase CardIds.DieInsects_TB_BaconShop_HP_019:\r\n\t\t\treturn DieInsects;\r\n\t\tcase CardIds.FireTheCannons:\r\n\t\t\treturn FireTheCannons;\r\n\t\tcase CardIds.NefariousFire:\r\n\t\t\treturn NefariousFire;\r\n\t\tcase CardIds.MurlocKing:\r\n\t\t\treturn MurlocKing;\r\n\t\tcase CardIds.AimLeftToken:\r\n\t\t\treturn AimLeft;\r\n\t\tcase CardIds.AimRightToken:\r\n\t\t\treturn AimRight;\r\n\t\tcase CardIds.AimLowToken:\r\n\t\t\treturn AimLow;\r\n\t\tcase CardIds.AimHighToken:\r\n\t\t\treturn AimHigh;\r\n\r\n\t\t// Anomalies\r\n\t\tcase CardIds.BlessedOrBlighted_BG27_Anomaly_726:\r\n\t\t\treturn BlessedOrBlighted;\r\n\t\tcase CardIds.AnomalousTwin_BG27_Anomaly_560:\r\n\t\t\treturn AnomalousTwin;\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn BoonOfBeetles;\r\n\r\n\t\t// Spells\r\n\t\tcase CardIds.ToxicTumbleweed_BG28_641:\r\n\t\t\treturn ToxicTumbleweed;\r\n\t\tcase CardIds.UpperHand_BG28_573:\r\n\t\t\treturn UpperHand;\r\n\t\tcase CardIds.FleetingVigor_BG28_519:\r\n\t\t\treturn FleetingVigor;\r\n\r\n\t\t// Minions\r\n\t\tcase CardIds.AmberGuardian_BG24_500:\r\n\t\tcase CardIds.AmberGuardian_BG24_500_G:\r\n\t\t\treturn AmberGuardian;\r\n\t\t// case CardIds.SanctumRester_BG26_356:\r\n\t\t// case CardIds.SanctumRester_BG26_356_G:\r\n\t\t// \treturn SanctumRester;\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012:\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012_G:\r\n\t\t\treturn CorruptedMyrmidon;\r\n\t\tcase CardIds.MantidQueen_BG22_402:\r\n\t\tcase CardIds.MantidQueen_BG22_402_G:\r\n\t\t\treturn MantidQueen;\r\n\t\tcase CardIds.CarbonicCopy_BG27_503:\r\n\t\tcase CardIds.CarbonicCopy_BG27_503_G:\r\n\t\t\treturn CarbonicCopy;\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079:\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079_G:\r\n\t\t\treturn HawkstriderHerald;\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904:\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904_G:\r\n\t\t\treturn AudaciousAnchor;\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810:\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810_G:\r\n\t\t\treturn ThousandthPaperDrake;\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811:\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811_G:\r\n\t\t\treturn YulonFortuneGranter;\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872:\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872_G:\r\n\t\t// \treturn HoardingHatespawn;\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875:\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875_G:\r\n\t\t\treturn TheUninvitedGuest;\r\n\t\tcase CardIds.Sandy_BGDUO_125:\r\n\t\tcase CardIds.Sandy_BGDUO_125_G:\r\n\t\t\treturn Sandy;\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy:\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy_G:\r\n\t\t\treturn ElderTaggawag;\r\n\t\tcase CardIds.SunScreener_BG30_101:\r\n\t\tcase CardIds.SunScreener_BG30_101_G:\r\n\t\t\treturn SunScreener;\r\n\r\n\t\tdefault:\r\n\t\t\tconst candidate = cardMappings[cardId];\r\n\t\t\tif (hasStartOfCombat(candidate)) {\r\n\t\t\t\treturn candidate;\r\n\t\t\t}\r\n\t\t\treturn null;\r\n\t}\r\n};\r\n\r\nconst onStartOfCombatTriggered = (iteration: number, triggeredCardId: string, playerEntity: BgsPlayerEntity) => {\r\n\t// Some procs are iso-functional, and don't update the promo portrait\r\n\tconst promoPortraits = playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t);\r\n\tif (promoPortraits.length === 0 || iteration === 0 || iteration > promoPortraits.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tswitch (triggeredCardId) {\r\n\t\tcase CardIds.StolenGold:\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\tcase CardIds.SwattingInsects:\r\n\t\tcase CardIds.RebornRites:\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn;\r\n\t}\r\n\r\n\tconst promoPortrait = promoPortraits[iteration - 1];\r\n\tpromoPortrait.scriptDataNum1--;\r\n};\r\n\r\nconst getPromoPortraitCount = (playerEntity: BgsPlayerEntity) => {\r\n\treturn playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t).length;\r\n};\r\n"]}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@firestone-hs/simulate-bgs-battle",
3
- "version": "1.1.730",
3
+ "version": "1.1.732",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "lint": "eslint --color --fix --ext .ts .",
7
7
  "benchmark": "node -r ts-node/register test/full-game/bench.ts",
8
- "test-board": "ts-node test/full-game/full-test.ts",
8
+ "test-board": "env -u TS_NODE_TRANSPILE_ONLY -u TS_NODE_PROJECT ts-node test/full-game/full-test.ts",
9
9
  "test:unit": "node -r ts-node/register --test test/unit/hand-minion-priority.test.ts test/unit/tavern-spell-stat-buff.test.ts test/unit/resolve-trinket-hero-power.test.ts test/unit/performance-hotpaths.test.ts test/unit/simulate-single-combat.test.ts test/unit/damage-cap.test.ts",
10
- "test-board-ss": "node --stack-size=100 --trace-uncaught -r ts-node/register test/full-game/full-test.ts",
11
- "test-board-prof": "node --inspect-brk -r ts-node/register test/full-game/full-test.ts",
10
+ "test-board-ss": "env -u TS_NODE_TRANSPILE_ONLY -u TS_NODE_PROJECT node --stack-size=100 --trace-uncaught -r ts-node/register test/full-game/full-test.ts",
11
+ "test-board-prof": "env -u TS_NODE_TRANSPILE_ONLY -u TS_NODE_PROJECT node --inspect-brk -r ts-node/register test/full-game/full-test.ts",
12
12
  "build": "tsc && webpack --color",
13
13
  "build-tsc": "rm -rf dist && tsc",
14
14
  "package": "sam package --template-file template.yaml --s3-bucket com.zerotoheroes.artifact --output-template-file template.packaged.yaml",