@firestone-hs/simulate-bgs-battle 1.1.759 → 1.1.762

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 (58) hide show
  1. package/dist/board-entity.d.ts +1 -0
  2. package/dist/board-entity.js.map +1 -1
  3. package/dist/cards/cards-data.d.ts +1 -0
  4. package/dist/cards/cards-data.js +5 -0
  5. package/dist/cards/cards-data.js.map +1 -1
  6. package/dist/cards/impl/bg-spell/brood-of-nozdormu.js +1 -1
  7. package/dist/cards/impl/bg-spell/brood-of-nozdormu.js.map +1 -1
  8. package/dist/cards/impl/enchantments/deaths-embrace.js +1 -3
  9. package/dist/cards/impl/enchantments/deaths-embrace.js.map +1 -1
  10. package/dist/cards/impl/enchantments/doppelganger.js +1 -1
  11. package/dist/cards/impl/enchantments/doppelganger.js.map +1 -1
  12. package/dist/cards/impl/enchantments/spell-siphon.d.ts +2 -2
  13. package/dist/cards/impl/enchantments/spell-siphon.js +46 -5
  14. package/dist/cards/impl/enchantments/spell-siphon.js.map +1 -1
  15. package/dist/cards/impl/minion/bramble-tunneler.js +1 -1
  16. package/dist/cards/impl/minion/bramble-tunneler.js.map +1 -1
  17. package/dist/cards/impl/minion/drustfallen-butcher.js +1 -1
  18. package/dist/cards/impl/minion/drustfallen-butcher.js.map +1 -1
  19. package/dist/cards/impl/minion/faceless-converter.js +4 -2
  20. package/dist/cards/impl/minion/faceless-converter.js.map +1 -1
  21. package/dist/cards/impl/minion/joyous.js +2 -3
  22. package/dist/cards/impl/minion/joyous.js.map +1 -1
  23. package/dist/cards/impl/minion/lurking-leviathan.js +2 -1
  24. package/dist/cards/impl/minion/lurking-leviathan.js.map +1 -1
  25. package/dist/cards/impl/minion/relentless-deflector.js +3 -0
  26. package/dist/cards/impl/minion/relentless-deflector.js.map +1 -1
  27. package/dist/cards/impl/minion/sinrunner-blanchy.js +1 -0
  28. package/dist/cards/impl/minion/sinrunner-blanchy.js.map +1 -1
  29. package/dist/cards/impl/minion/tasty-lobster.js +3 -1
  30. package/dist/cards/impl/minion/tasty-lobster.js.map +1 -1
  31. package/dist/cards/impl/minion/the-shadow-of-doubt.js +3 -2
  32. package/dist/cards/impl/minion/the-shadow-of-doubt.js.map +1 -1
  33. package/dist/cards/impl/minion/underrot-spawn.js +1 -1
  34. package/dist/cards/impl/minion/underrot-spawn.js.map +1 -1
  35. package/dist/cards/impl/minion/vicious-mindslasher.js +3 -2
  36. package/dist/cards/impl/minion/vicious-mindslasher.js.map +1 -1
  37. package/dist/cards/impl/minion/wildfire-elemental.js +2 -1
  38. package/dist/cards/impl/minion/wildfire-elemental.js.map +1 -1
  39. package/dist/cards/impl/trinket/hammer-of-twilight.js +10 -3
  40. package/dist/cards/impl/trinket/hammer-of-twilight.js.map +1 -1
  41. package/dist/input-sanitation.js +1 -0
  42. package/dist/input-sanitation.js.map +1 -1
  43. package/dist/simulation/death-effects.js +3 -0
  44. package/dist/simulation/death-effects.js.map +1 -1
  45. package/dist/simulation/deathrattle-orchestration.js +2 -1
  46. package/dist/simulation/deathrattle-orchestration.js.map +1 -1
  47. package/dist/simulation/minion-death.js +5 -1
  48. package/dist/simulation/minion-death.js.map +1 -1
  49. package/dist/simulation/simulator.js +5 -11
  50. package/dist/simulation/simulator.js.map +1 -1
  51. package/dist/simulation/start-of-combat/soc-action-processor.d.ts +1 -1
  52. package/dist/simulation/start-of-combat/soc-action-processor.js +10 -8
  53. package/dist/simulation/start-of-combat/soc-action-processor.js.map +1 -1
  54. package/dist/simulation/start-of-combat/soc-minion.js +3 -12
  55. package/dist/simulation/start-of-combat/soc-minion.js.map +1 -1
  56. package/dist/simulation/summon-when-space.js +1 -0
  57. package/dist/simulation/summon-when-space.js.map +1 -1
  58. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"deathrattle-orchestration.js","sourceRoot":"","sources":["../../src/simulation/deathrattle-orchestration.ts"],"names":[],"mappings":"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","sourcesContent":["import { Race } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { isWhelp } from '../cards/cards-data';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { hasCorrectTribe } from '../utils';\r\nimport { applyAvengeEffects } from './avenge';\r\nimport { applyAfterDeathEffects } from './death-effects';\r\nimport {\r\n\tapplyAfterMinionDiesEffect,\r\n\tapplyWheneverMinionDiesEffect,\r\n\thandleAfterMinionKillsEffect,\r\n} from './deathrattle-effects';\r\nimport { spawnEntities, spawnEntitiesFromDeathrattle } from './deathrattle-spawns';\r\nimport { FullGameState, PlayerState } from './internal-game-state';\r\nimport { handleRebornForEntity } from './reborn';\r\nimport { performEntitySpawns } from './spawns';\r\n\r\n// FIXME:\r\n// From Mitchell on Discord:\r\n// - Minions die left to right\r\n// - When a minion dies, it procs natural deathrattle, added deathrattles, and then all avenges progress\r\n// by 1 (and trigger as necessary)\r\n// - Then next minion\r\n// - After ALL deathrattles and avenges are done, Reborn triggers\r\n// - (Ideally after all of that I would want Feathermane to trigger, but that is not what it does right now.\r\n// Right now it triggers at deathrattle speed rather than after Reborn speed)\r\nlet _deathEffectsDepth = 0;\r\n\r\nexport const orchestrateMinionDeathEffects = (\r\n\tdeathrattleInput: DeathrattleInput,\r\n\tprocessAvenge = true,\r\n\tprocessReborn = true,\r\n) => {\r\n\t_deathEffectsDepth++;\r\n\tif (_deathEffectsDepth > 100) {\r\n\t\tconsole.error('Infinite recursion detected at depth', _deathEffectsDepth);\r\n\t\tconsole.error(\r\n\t\t\t'Player dead entities:',\r\n\t\t\tdeathrattleInput.playerDeadEntities.map((e) => e.cardId),\r\n\t\t);\r\n\t\tconsole.error(\r\n\t\t\t'Opponent dead entities:',\r\n\t\t\tdeathrattleInput.opponentDeadEntities.map((e) => e.cardId),\r\n\t\t);\r\n\t\tconsole.error(\r\n\t\t\t'Player board:',\r\n\t\t\tdeathrattleInput.gameState.gameState.player.board.map((e) => e.cardId),\r\n\t\t);\r\n\t\tconsole.error(\r\n\t\t\t'Opponent board:',\r\n\t\t\tdeathrattleInput.gameState.gameState.opponent.board.map((e) => e.cardId),\r\n\t\t);\r\n\t\t_deathEffectsDepth--;\r\n\t\treturn;\r\n\t}\r\n\r\n\thandleAfterMinionsKillEffects(deathrattleInput);\r\n\r\n\t// Not sure about this\r\n\thandleWheneverMinionsDieEffects(deathrattleInput);\r\n\r\n\tconst playerBoardBefore = [...deathrattleInput.gameState.gameState.player.board];\r\n\tconst opponentBoardBefore = [...deathrattleInput.gameState.gameState.opponent.board];\r\n\r\n\tconst entitiesFromDeathrattles = processDeathrattles(deathrattleInput, processAvenge);\r\n\r\n\t// When a Silent Enforcer dies, it deals damage to other minions, then Soul Juggler damages the minions\r\n\t// **before** they completely die and spawn their own deathrattles\r\n\thandleAfterMinionsDieEffects(deathrattleInput);\r\n\r\n\t// Hack to try and fix how reborn indices are handled when there are spawns during the deathrattle phase\r\n\t// Ideally, this should probably be rewritten completely to keep the dead entities in the board itself\r\n\t// so we can use that as a source for the spawn index. However this is a big rewrite with lots of\r\n\t// potential side-effects\r\n\tconst playerBoardAfter = [...deathrattleInput.gameState.gameState.player.board];\r\n\tconst opponentBoardAfter = [...deathrattleInput.gameState.gameState.opponent.board];\r\n\tconst opponentIndexOfSpawnedEntities = opponentBoardAfter\r\n\t\t.filter((entity) => !opponentBoardBefore.includes(entity))\r\n\t\t.map((entity) => opponentBoardAfter.length - opponentBoardAfter.indexOf(entity) - 1);\r\n\tconst playerIndexOfSpawnedEntities = playerBoardAfter\r\n\t\t.filter((entity) => !playerBoardBefore.includes(entity))\r\n\t\t.map((entity) => playerBoardAfter.length - playerBoardAfter.indexOf(entity) - 1);\r\n\tdeathrattleInput.opponentDeadEntityIndexesFromRight = deathrattleInput.opponentDeadEntityIndexesFromRight.map(\r\n\t\t(previousIndex) => {\r\n\t\t\topponentIndexOfSpawnedEntities.forEach((index) => {\r\n\t\t\t\tif (index < previousIndex) {\r\n\t\t\t\t\tpreviousIndex++;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\treturn previousIndex;\r\n\t\t},\r\n\t);\r\n\tdeathrattleInput.playerDeadEntityIndexesFromRight = deathrattleInput.playerDeadEntityIndexesFromRight.map(\r\n\t\t(previousIndex) => {\r\n\t\t\tplayerIndexOfSpawnedEntities.forEach((index) => {\r\n\t\t\t\tif (index < previousIndex) {\r\n\t\t\t\t\tpreviousIndex++;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\treturn previousIndex;\r\n\t\t},\r\n\t);\r\n\r\n\tif (processReborn) {\r\n\t\tprocessReborns(deathrattleInput);\r\n\t}\r\n\r\n\tconst entitiesFromFeathermanes = processFeathermaneEffects(deathrattleInput);\r\n\thandlePostDeathrattleEffects(deathrattleInput, [...entitiesFromDeathrattles, ...entitiesFromFeathermanes]);\r\n\r\n\t_deathEffectsDepth--;\r\n};\r\n\r\nconst handleAfterMinionsKillEffects = (deathrattleInput: DeathrattleInput) => {\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\thandleAfterMinionKillsEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tplayerDeadEntityIndexesFromRight[i][j],\r\n\t\t\t\t\tplayerStates[i].board,\r\n\t\t\t\t\tplayerStates[i].player,\r\n\t\t\t\t\tplayerStates[1 - i].board,\r\n\t\t\t\t\tplayerStates[1 - i].player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handleWheneverMinionsDieEffects = (deathrattleInput: DeathrattleInput) => {\r\n\t// Wildfire Element is applied first, before the DR spawns\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tapplyWheneverMinionDiesEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tplayerDeadEntityIndexesFromRight[i][j],\r\n\t\t\t\t\tplayerStates[i].board,\r\n\t\t\t\t\tplayerStates[i].player,\r\n\t\t\t\t\tplayerStates[1 - i].board,\r\n\t\t\t\t\tplayerStates[1 - i].player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handleAfterMinionsDieEffects = (deathrattleInput: DeathrattleInput) => {\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tapplyAfterMinionDiesEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tplayerDeadEntityIndexesFromRight[i][j],\r\n\t\t\t\t\tplayerStates[i].board,\r\n\t\t\t\t\tplayerStates[i].player,\r\n\t\t\t\t\tplayerStates[1 - i].board,\r\n\t\t\t\t\tplayerStates[1 - i].player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst processDeathrattles = (deathrattleInput: DeathrattleInput, processAvenge = true): BoardEntity[] => {\r\n\tconst entitiesFromDeathrattles: BoardEntity[] = [];\r\n\t// Deathrattles are handled left to right\r\n\t// Then for each minion, natural deathrattles are processed first, then enchantments\r\n\t// http://replays.firestoneapp.com/?reviewId=ec5428bf-a599-4f4c-bea9-8acad5075cb8&turn=11&action=1\r\n\t// http://replays.firestoneapp.com/?reviewId=f32e734a-d5a2-4fa4-ad10-94019969cdd7&turn=6&action=22\r\n\t// http://replays.firestoneapp.com/?reviewId=ea9503c9-2795-49f0-866b-9ea856cec7df&turn=11&action=3\r\n\t// http://replays.firestoneapp.com/?reviewId=1ff37e17-704c-4a73-8c78-377c52b6cb42&turn=13&action=1 is a trap: the enchantment is on the first\r\n\t// minion, but the DR is on the second one.\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\t// Issue: we should process all deathrattles first, then all avenge. If multiple minions die at the same time,\r\n\t\t// the current implementation processes the first minion completely (DR + avenge), then the second one\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\t// Entities are processed left to right\r\n\t\t\t// TODO: in fact, the processing order is summoning order, so maybe we can just use the entityId\r\n\t\t\t// to determine the order? https://x.com/LoewenMitchell/status/1750792974383173676?s=20\r\n\t\t\t// \"It should be summoned order (which is most cases would be left to right but mid-combat that could change).\"\r\n\t\t\t// This doesn't actually work: http://replays.firestoneapp.com/?reviewId=ec5428bf-a599-4f4c-bea9-8acad5075cb8&turn=11&action=6\r\n\t\t\t// deadEntities.sort((a, b) => a.entityId - b.entityId);\r\n\t\t\t// So we would need to find another proxy for the order\r\n\t\t\tconst spawns = processDeathrattleForMinions(\r\n\t\t\t\tdeadEntities,\r\n\t\t\t\tplayerDeadEntityIndexesFromRight[i],\r\n\t\t\t\tplayerStates[i],\r\n\t\t\t\tplayerStates[1 - i],\r\n\t\t\t\tdeathrattleInput,\r\n\t\t\t\tprocessAvenge,\r\n\t\t\t);\r\n\t\t\tentitiesFromDeathrattles.push(...spawns);\r\n\t\t\t// for (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t// \tconst deadEntity = deadEntities[j];\r\n\t\t\t// \tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t// \tconst deadEntityPlayerState = playerStates[i];\r\n\t\t\t// \tconst otherPlayerState = playerStates[1 - i];\r\n\t\t\t// \tconst spawns = processDeathrattleForMinion(\r\n\t\t\t// \t\tdeadEntity,\r\n\t\t\t// \t\tindexFromRight,\r\n\t\t\t// \t\tdeadEntities,\r\n\t\t\t// \t\tdeadEntityPlayerState,\r\n\t\t\t// \t\totherPlayerState,\r\n\t\t\t// \t\tdeathrattleInput.gameState,\r\n\t\t\t// \t\tprocessAvenge,\r\n\t\t\t// \t);\r\n\t\t\t// \tentitiesFromDeathrattles.push(...spawns);\r\n\t\t\t// }\r\n\t\t}\r\n\t}\r\n\treturn entitiesFromDeathrattles;\r\n};\r\n\r\nconst processFeathermaneEffects = (deathrattleInput: DeathrattleInput, processAvenge = true): BoardEntity[] => {\r\n\tconst entitiesFromDeathrattles: BoardEntity[] = [];\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\t// Entities are processed left to right\r\n\t\t\t// TODO: in fact, the processing order is summoning order, so maybe we can just use the entityId\r\n\t\t\t// to determine the order? https://x.com/LoewenMitchell/status/1750792974383173676?s=20\r\n\t\t\t// \"It should be summoned order (which is most cases would be left to right but mid-combat that could change).\"\r\n\t\t\t// This doesn't actually work: http://replays.firestoneapp.com/?reviewId=ec5428bf-a599-4f4c-bea9-8acad5075cb8&turn=11&action=6\r\n\t\t\t// deadEntities.sort((a, b) => a.entityId - b.entityId);\r\n\t\t\t// So we would need to find another proxy for the order\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t\tconst modifiedIndexFromRight = Math.min(playerStates[i].board.length, indexFromRight);\r\n\t\t\t\tconst deadEntityPlayerState = playerStates[i];\r\n\t\t\t\tconst otherPlayerState = playerStates[1 - i];\r\n\t\t\t\tconst spawns = processFeathermaneForMinion(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\tdeadEntities,\r\n\t\t\t\t\tdeadEntityPlayerState,\r\n\t\t\t\t\totherPlayerState,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t\tprocessAvenge,\r\n\t\t\t\t);\r\n\t\t\t\tentitiesFromDeathrattles.push(...spawns);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn entitiesFromDeathrattles;\r\n};\r\n\r\nconst processFeathermaneForMinion = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n\tprocessAvenge = true,\r\n) => {\r\n\tconst maxSpawns = 7 - deadEntityPlayerState.board.length;\r\n\tconst allSpawns = [];\r\n\r\n\t// Feathermane\r\n\tif (\r\n\t\thasCorrectTribe(deadEntity, deadEntityPlayerState.player, Race.BEAST, gameState.anomalies, gameState.allCards)\r\n\t) {\r\n\t\tconst feathermanes =\r\n\t\t\tdeadEntityPlayerState.player.hand\r\n\t\t\t\t?.filter((e) => !e.locked)\r\n\t\t\t\t.filter(\r\n\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\te.cardId === CardIds.FreeFlyingFeathermane_BG27_014 ||\r\n\t\t\t\t\t\te.cardId === CardIds.FreeFlyingFeathermane_BG27_014_G,\r\n\t\t\t\t) ?? [];\r\n\t\tfor (const feathermaneSpawn of feathermanes) {\r\n\t\t\tif (allSpawns.length >= maxSpawns) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tfeathermaneSpawn.locked = true;\r\n\t\t\tconst spawns = spawnEntities(\r\n\t\t\t\tfeathermaneSpawn.cardId,\r\n\t\t\t\t1,\r\n\t\t\t\tdeadEntityPlayerState.board,\r\n\t\t\t\tdeadEntityPlayerState.player,\r\n\t\t\t\totherPlayerState.board,\r\n\t\t\t\totherPlayerState.player,\r\n\t\t\t\tgameState,\r\n\t\t\t\tdeadEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\ttrue,\r\n\t\t\t\t{ ...feathermaneSpawn } as BoardEntity,\r\n\t\t\t);\r\n\r\n\t\t\t// So that it can be flagged as \"unspawned\" if it is not spawned in the end\r\n\t\t\tfor (const spawn of spawns) {\r\n\t\t\t\tspawn.onCanceledSummon = () => (feathermaneSpawn.locked = false);\r\n\t\t\t\t// spawn.backRef = feathermaneSpawn;\r\n\t\t\t}\r\n\t\t\tallSpawns.push(...spawns);\r\n\t\t}\r\n\t}\r\n\r\n\tperformEntitySpawns(\r\n\t\tallSpawns,\r\n\t\tdeadEntityPlayerState.board,\r\n\t\tdeadEntityPlayerState.player,\r\n\t\tdeadEntity,\r\n\t\tindexFromRight,\r\n\t\totherPlayerState.board,\r\n\t\totherPlayerState.player,\r\n\t\tgameState,\r\n\t);\r\n\treturn allSpawns;\r\n};\r\n\r\nconst processDeathrattleForMinions = (\r\n\tdeadEntities: BoardEntity[],\r\n\tplayerDeadEntityIndexesFromRight: number[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tinput: DeathrattleInput,\r\n\tprocessAvenge = true,\r\n) => {\r\n\tconst entitiesFromDeathrattles: BoardEntity[] = [];\r\n\r\n\t// Natural deathrattles & enchantments\r\n\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\tconst deadEntity = deadEntities[j];\r\n\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[j];\r\n\t\tconst drEntities = handleNaturalDeathrattle(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntities,\r\n\t\t\tdeadEntityPlayerState,\r\n\t\t\totherPlayerState,\r\n\t\t\tinput.gameState,\r\n\t\t);\r\n\r\n\t\tentitiesFromDeathrattles.push(...drEntities);\r\n\t}\r\n\r\n\t// Avenge\r\n\tlet avengeEntities = [];\r\n\tif (processAvenge) {\r\n\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[j];\r\n\t\t\tavengeEntities = applyAvengeEffects(\r\n\t\t\t\tdeadEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\tdeadEntityPlayerState.board,\r\n\t\t\t\tdeadEntityPlayerState.player,\r\n\t\t\t\totherPlayerState.board,\r\n\t\t\t\totherPlayerState.player,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t\tentitiesFromDeathrattles,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\tconst allAfterDeathEntities = [];\r\n\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\tconst deadEntity = deadEntities[j];\r\n\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[j];\r\n\t\tconst afterDeathEntities = applyAfterDeathEffects(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntityPlayerState.board,\r\n\t\t\tdeadEntityPlayerState.player,\r\n\t\t\totherPlayerState.board,\r\n\t\t\totherPlayerState.player,\r\n\t\t\tinput.gameState,\r\n\t\t);\r\n\t\tallAfterDeathEntities.push(...afterDeathEntities);\r\n\t}\r\n\r\n\treturn [...entitiesFromDeathrattles, ...avengeEntities, ...allAfterDeathEntities];\r\n};\r\n\r\nexport const processDeathrattleForMinion = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n\tprocessAvenge = true,\r\n) => {\r\n\tconst drEntities = handleNaturalDeathrattle(\r\n\t\tdeadEntity,\r\n\t\tindexFromRight,\r\n\t\tdeadEntities,\r\n\t\tdeadEntityPlayerState,\r\n\t\totherPlayerState,\r\n\t\tgameState,\r\n\t);\r\n\t// Avenge trigger before reborn\r\n\t// http://replays.firestoneapp.com/?reviewId=5bb20eb8-e0ca-47ab-adc7-13134716d568&turn=7&action=6\r\n\tlet avengeEntities = [];\r\n\tlet afterDeathEntities = [];\r\n\tif (processAvenge) {\r\n\t\tavengeEntities = applyAvengeEffects(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntityPlayerState.board,\r\n\t\t\tdeadEntityPlayerState.player,\r\n\t\t\totherPlayerState.board,\r\n\t\t\totherPlayerState.player,\r\n\t\t\tgameState,\r\n\t\t\t[...drEntities],\r\n\t\t);\r\n\r\n\t\t// TODO: Feathermane should be applied after the Reborn effects have all been processed\r\n\t\t// Secrets should be processed here (\"at Avenge speed\")\r\n\t\tafterDeathEntities = applyAfterDeathEffects(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntityPlayerState.board,\r\n\t\t\tdeadEntityPlayerState.player,\r\n\t\t\totherPlayerState.board,\r\n\t\t\totherPlayerState.player,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n\treturn [...drEntities, ...avengeEntities, ...afterDeathEntities];\r\n};\r\n\r\nconst handleNaturalDeathrattle = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n): readonly BoardEntity[] => {\r\n\tconst modifiedIndexFromRight = Math.min(deadEntityPlayerState.board.length, indexFromRight);\r\n\t// const allSpawns = [];\r\n\t// const spawnsToSpawn = [];\r\n\tfor (const dr of deadEntity.rememberedDeathrattles ?? []) {\r\n\t\tconst entityToProcess: BoardEntity = {\r\n\t\t\t...deadEntity,\r\n\t\t\toriginalCardId: deadEntity.cardId,\r\n\t\t\trememberedDeathrattles: undefined,\r\n\t\t\tdeathrattleRepeats: dr.repeats ?? 1,\r\n\t\t\tscriptDataNum1: dr.tagScriptDataNum1,\r\n\t\t\tscriptDataNum2: dr.tagScriptDataNum2,\r\n\t\t\tcardId: dr.cardId,\r\n\t\t\tpendingAttackBuffs: [],\r\n\t\t\t// For Corrupted Bristler\r\n\t\t\tenchantments: deadEntity.enchantments.filter((e) => e.cardId?.startsWith(CardIds.BloodGem)),\r\n\t\t\tmemory:\r\n\t\t\t\tdr.memory == null\r\n\t\t\t\t\t? null\r\n\t\t\t\t\t: Array.isArray(dr.memory)\r\n\t\t\t\t\t? dr.memory.map((mem) => ({ ...mem }))\r\n\t\t\t\t\t: { ...dr.memory },\r\n\t\t};\r\n\t\tconst spawns = handleNaturalDeathrattle(\r\n\t\t\tentityToProcess,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntities,\r\n\t\t\tdeadEntityPlayerState,\r\n\t\t\totherPlayerState,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\t// The spawns have already been processed in the \"handleNaturalDeathrattle\" method\r\n\t\t// spawnsToSpawn.push(...spawns);\r\n\t\t// allSpawns.push(...spawns);\r\n\t}\r\n\r\n\tconst entitiesFromNativeDeathrattle: readonly BoardEntity[] = spawnEntitiesFromDeathrattle(\r\n\t\tdeadEntity,\r\n\t\tmodifiedIndexFromRight,\r\n\t\tdeadEntityPlayerState.board,\r\n\t\tdeadEntityPlayerState.player,\r\n\t\totherPlayerState.board,\r\n\t\totherPlayerState.player,\r\n\t\tdeadEntities,\r\n\t\tgameState,\r\n\t);\r\n\r\n\treturn entitiesFromNativeDeathrattle;\r\n};\r\n\r\nconst processReborns = (deathrattleInput: DeathrattleInput) => {\r\n\t// const entitiesFromReborn: BoardEntity[] = [];\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t\tconst modifiedIndexFromRight = Math.min(playerStates[i].board.length, indexFromRight);\r\n\t\t\t\tconst deadEntityPlayerState = playerStates[i];\r\n\t\t\t\tconst otherPlayerState = playerStates[1 - i];\r\n\t\t\t\thandleRebornForEntity(\r\n\t\t\t\t\tdeadEntityPlayerState.board,\r\n\t\t\t\t\tdeadEntityPlayerState.player,\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\totherPlayerState.board,\r\n\t\t\t\t\totherPlayerState.player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handlePostDeathrattleEffects = (deathrattleInput: DeathrattleInput, entitiesFromDeathrattles: BoardEntity[]) => {\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tconst deadEntityPlayerState = playerStates[i];\r\n\t\tconst otherPlayerState = playerStates[1 - i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\t// Process from right to left, so that we can set the hasAttacked attribute properly\r\n\t\t\t// If two minions die at the same time, both of which having attacked, but the third in line having not,\r\n\t\t\t// processing them from left to right means the first (leftmost) one will check its right neighbor, which\r\n\t\t\t// is the minion that hasn't attacked\r\n\t\t\tfor (let j = deadEntities.length - 1; j >= 0; j--) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t\tconst modifiedIndexFromRight = Math.min(playerStates[i].board.length, indexFromRight);\r\n\t\t\t\thandlePostDeathrattleEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\tdeadEntities,\r\n\t\t\t\t\tdeadEntityPlayerState,\r\n\t\t\t\t\totherPlayerState,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t\tentitiesFromDeathrattles,\r\n\t\t\t\t\tdeadEntityPlayerState.player.friendly,\r\n\t\t\t\t\tdeathrattleInput,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const handleDeathrattles = (deathrattleInput: DeathrattleInput) => {\r\n\torchestrateMinionDeathEffects(deathrattleInput, false, false);\r\n};\r\n\r\nconst handlePostDeathrattleEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n\tspawnedEntities: BoardEntity[],\r\n\tisPlayer: boolean,\r\n\tdeathrattleInput: DeathrattleInput,\r\n) => {\r\n\t// This doesn't work if the entity that was to the right died.\r\n\tconst entityRightToSpawns =\r\n\t\tindexFromRight === 0 ? null : deadEntityPlayerState.board[deadEntityPlayerState.board.length - indexFromRight];\r\n\t// To handle minions attack tokens\r\n\t// See http://replays.firestoneapp.com/?reviewId=0583d6a4-6ed0-4b20-894e-4ceb560894fe&turn=6&action=11\r\n\t// When a minion dies, the spawn are either elligible to attack next turn or not\r\n\t// If the minion right to the spawned minion has already attacked, then the spawned\r\n\t// minion cannot attack\r\n\tspawnedEntities.forEach((entity) => {\r\n\t\tentity.hasAttacked = deadEntity.hasAttacked > 1 ? 1 : entityRightToSpawns?.hasAttacked ?? undefined;\r\n\t});\r\n\r\n\tif (deadEntityPlayerState.player.questRewards?.includes(CardIds.RitualDagger_BG24_Reward_113)) {\r\n\t\tconst ogDeadEntity = gameState.sharedState.deaths.find((entity) => entity.entityId === deadEntity.entityId);\r\n\t\tif (ogDeadEntity) {\r\n\t\t\togDeadEntity.attack += 4;\r\n\t\t\togDeadEntity.health += 4;\r\n\t\t}\r\n\t}\r\n\r\n\t// ISSUE: when we do this, we change the minion's stats before processing deathrattle effects, which can mess\r\n\t// up the simulation in some cases (like Nightbane, Ignited)\r\n\t// FIX: we do it in postDeathrattleEfects, not when removing minions from the board\r\n\tif (deadEntityPlayerState.player.globalInfo.HauntedCarapaceAttackBonus > 0) {\r\n\t\tdeadEntity.attack = Math.max(\r\n\t\t\t0,\r\n\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.HauntedCarapaceAttackBonus,\r\n\t\t);\r\n\t}\r\n\tif (deadEntityPlayerState.player.globalInfo.HauntedCarapaceHealthBonus > 0) {\r\n\t\tdeadEntity.health = Math.max(\r\n\t\t\t1,\r\n\t\t\tdeadEntity.health - deadEntityPlayerState.player.globalInfo.HauntedCarapaceHealthBonus,\r\n\t\t);\r\n\t}\r\n\tif (\r\n\t\thasCorrectTribe(deadEntity, deadEntityPlayerState.player, Race.UNDEAD, gameState.anomalies, gameState.allCards)\r\n\t) {\r\n\t\tif (deadEntityPlayerState.player.globalInfo.UndeadAttackBonus > 0) {\r\n\t\t\tdeadEntity.attack = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.UndeadAttackBonus,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (deadEntityPlayerState.player.globalInfo.UndeadHealthBonus > 0) {\r\n\t\t\tdeadEntity.health = Math.max(\r\n\t\t\t\t1,\r\n\t\t\t\tdeadEntity.health - deadEntityPlayerState.player.globalInfo.UndeadHealthBonus,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\tif (\r\n\t\thasCorrectTribe(deadEntity, deadEntityPlayerState.player, Race.BEAST, gameState.anomalies, gameState.allCards)\r\n\t) {\r\n\t\tif (deadEntityPlayerState.player.globalInfo.GoldrinnBuffAtk > 0) {\r\n\t\t\tdeadEntity.attack = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.GoldrinnBuffAtk,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\tif (isWhelp(deadEntity.cardId, gameState.allCards)) {\r\n\t\tif (deadEntityPlayerState.player.globalInfo.WhelpAttackBuff > 0) {\r\n\t\t\tdeadEntity.attack = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.WhelpAttackBuff,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n};\r\n\r\ninterface DeathrattleInput {\r\n\tgameState: FullGameState;\r\n\tplayerDeadEntities: BoardEntity[];\r\n\tplayerDeadEntityIndexesFromRight: number[];\r\n\topponentDeadEntities: BoardEntity[];\r\n\topponentDeadEntityIndexesFromRight: number[];\r\n}\r\n"]}
1
+ {"version":3,"file":"deathrattle-orchestration.js","sourceRoot":"","sources":["../../src/simulation/deathrattle-orchestration.ts"],"names":[],"mappings":"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","sourcesContent":["import { Race } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { isWhelp } from '../cards/cards-data';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { hasCorrectTribe } from '../utils';\r\nimport { applyAvengeEffects } from './avenge';\r\nimport { applyAfterDeathEffects } from './death-effects';\r\nimport {\r\n\tapplyAfterMinionDiesEffect,\r\n\tapplyWheneverMinionDiesEffect,\r\n\thandleAfterMinionKillsEffect,\r\n} from './deathrattle-effects';\r\nimport { spawnEntities, spawnEntitiesFromDeathrattle } from './deathrattle-spawns';\r\nimport { FullGameState, PlayerState } from './internal-game-state';\r\nimport { handleRebornForEntity } from './reborn';\r\nimport { performEntitySpawns } from './spawns';\r\n\r\n// FIXME:\r\n// From Mitchell on Discord:\r\n// - Minions die left to right\r\n// - When a minion dies, it procs natural deathrattle, added deathrattles, and then all avenges progress\r\n// by 1 (and trigger as necessary)\r\n// - Then next minion\r\n// - After ALL deathrattles and avenges are done, Reborn triggers\r\n// - (Ideally after all of that I would want Feathermane to trigger, but that is not what it does right now.\r\n// Right now it triggers at deathrattle speed rather than after Reborn speed)\r\nlet _deathEffectsDepth = 0;\r\n\r\nexport const orchestrateMinionDeathEffects = (\r\n\tdeathrattleInput: DeathrattleInput,\r\n\tprocessAvenge = true,\r\n\tprocessReborn = true,\r\n) => {\r\n\t_deathEffectsDepth++;\r\n\tif (_deathEffectsDepth > 100) {\r\n\t\tconsole.error('Infinite recursion detected at depth', _deathEffectsDepth);\r\n\t\tconsole.error(\r\n\t\t\t'Player dead entities:',\r\n\t\t\tdeathrattleInput.playerDeadEntities.map((e) => e.cardId),\r\n\t\t);\r\n\t\tconsole.error(\r\n\t\t\t'Opponent dead entities:',\r\n\t\t\tdeathrattleInput.opponentDeadEntities.map((e) => e.cardId),\r\n\t\t);\r\n\t\tconsole.error(\r\n\t\t\t'Player board:',\r\n\t\t\tdeathrattleInput.gameState.gameState.player.board.map((e) => e.cardId),\r\n\t\t);\r\n\t\tconsole.error(\r\n\t\t\t'Opponent board:',\r\n\t\t\tdeathrattleInput.gameState.gameState.opponent.board.map((e) => e.cardId),\r\n\t\t);\r\n\t\t_deathEffectsDepth--;\r\n\t\treturn;\r\n\t}\r\n\r\n\thandleAfterMinionsKillEffects(deathrattleInput);\r\n\r\n\t// Not sure about this\r\n\thandleWheneverMinionsDieEffects(deathrattleInput);\r\n\r\n\tconst playerBoardBefore = [...deathrattleInput.gameState.gameState.player.board];\r\n\tconst opponentBoardBefore = [...deathrattleInput.gameState.gameState.opponent.board];\r\n\r\n\tconst entitiesFromDeathrattles = processDeathrattles(deathrattleInput, processAvenge);\r\n\r\n\t// When a Silent Enforcer dies, it deals damage to other minions, then Soul Juggler damages the minions\r\n\t// **before** they completely die and spawn their own deathrattles\r\n\thandleAfterMinionsDieEffects(deathrattleInput);\r\n\r\n\t// Hack to try and fix how reborn indices are handled when there are spawns during the deathrattle phase\r\n\t// Ideally, this should probably be rewritten completely to keep the dead entities in the board itself\r\n\t// so we can use that as a source for the spawn index. However this is a big rewrite with lots of\r\n\t// potential side-effects\r\n\tconst playerBoardAfter = [...deathrattleInput.gameState.gameState.player.board];\r\n\tconst opponentBoardAfter = [...deathrattleInput.gameState.gameState.opponent.board];\r\n\tconst opponentIndexOfSpawnedEntities = opponentBoardAfter\r\n\t\t.filter((entity) => !opponentBoardBefore.includes(entity))\r\n\t\t.map((entity) => opponentBoardAfter.length - opponentBoardAfter.indexOf(entity) - 1);\r\n\tconst playerIndexOfSpawnedEntities = playerBoardAfter\r\n\t\t.filter((entity) => !playerBoardBefore.includes(entity))\r\n\t\t.map((entity) => playerBoardAfter.length - playerBoardAfter.indexOf(entity) - 1);\r\n\tdeathrattleInput.opponentDeadEntityIndexesFromRight = deathrattleInput.opponentDeadEntityIndexesFromRight.map(\r\n\t\t(previousIndex) => {\r\n\t\t\topponentIndexOfSpawnedEntities.forEach((index) => {\r\n\t\t\t\tif (index < previousIndex) {\r\n\t\t\t\t\tpreviousIndex++;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\treturn previousIndex;\r\n\t\t},\r\n\t);\r\n\tdeathrattleInput.playerDeadEntityIndexesFromRight = deathrattleInput.playerDeadEntityIndexesFromRight.map(\r\n\t\t(previousIndex) => {\r\n\t\t\tplayerIndexOfSpawnedEntities.forEach((index) => {\r\n\t\t\t\tif (index < previousIndex) {\r\n\t\t\t\t\tpreviousIndex++;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\treturn previousIndex;\r\n\t\t},\r\n\t);\r\n\r\n\tif (processReborn) {\r\n\t\tprocessReborns(deathrattleInput);\r\n\t}\r\n\r\n\tconst entitiesFromFeathermanes = processFeathermaneEffects(deathrattleInput);\r\n\thandlePostDeathrattleEffects(deathrattleInput, [...entitiesFromDeathrattles, ...entitiesFromFeathermanes]);\r\n\r\n\t_deathEffectsDepth--;\r\n};\r\n\r\nconst handleAfterMinionsKillEffects = (deathrattleInput: DeathrattleInput) => {\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\thandleAfterMinionKillsEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tplayerDeadEntityIndexesFromRight[i][j],\r\n\t\t\t\t\tplayerStates[i].board,\r\n\t\t\t\t\tplayerStates[i].player,\r\n\t\t\t\t\tplayerStates[1 - i].board,\r\n\t\t\t\t\tplayerStates[1 - i].player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handleWheneverMinionsDieEffects = (deathrattleInput: DeathrattleInput) => {\r\n\t// Wildfire Element is applied first, before the DR spawns\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tapplyWheneverMinionDiesEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tplayerDeadEntityIndexesFromRight[i][j],\r\n\t\t\t\t\tplayerStates[i].board,\r\n\t\t\t\t\tplayerStates[i].player,\r\n\t\t\t\t\tplayerStates[1 - i].board,\r\n\t\t\t\t\tplayerStates[1 - i].player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handleAfterMinionsDieEffects = (deathrattleInput: DeathrattleInput) => {\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tapplyAfterMinionDiesEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tplayerDeadEntityIndexesFromRight[i][j],\r\n\t\t\t\t\tplayerStates[i].board,\r\n\t\t\t\t\tplayerStates[i].player,\r\n\t\t\t\t\tplayerStates[1 - i].board,\r\n\t\t\t\t\tplayerStates[1 - i].player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst processDeathrattles = (deathrattleInput: DeathrattleInput, processAvenge = true): BoardEntity[] => {\r\n\tconst entitiesFromDeathrattles: BoardEntity[] = [];\r\n\t// Deathrattles are handled left to right\r\n\t// Then for each minion, natural deathrattles are processed first, then enchantments\r\n\t// http://replays.firestoneapp.com/?reviewId=ec5428bf-a599-4f4c-bea9-8acad5075cb8&turn=11&action=1\r\n\t// http://replays.firestoneapp.com/?reviewId=f32e734a-d5a2-4fa4-ad10-94019969cdd7&turn=6&action=22\r\n\t// http://replays.firestoneapp.com/?reviewId=ea9503c9-2795-49f0-866b-9ea856cec7df&turn=11&action=3\r\n\t// http://replays.firestoneapp.com/?reviewId=1ff37e17-704c-4a73-8c78-377c52b6cb42&turn=13&action=1 is a trap: the enchantment is on the first\r\n\t// minion, but the DR is on the second one.\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\t// Issue: we should process all deathrattles first, then all avenge. If multiple minions die at the same time,\r\n\t\t// the current implementation processes the first minion completely (DR + avenge), then the second one\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\t// Entities are processed left to right\r\n\t\t\t// TODO: in fact, the processing order is summoning order, so maybe we can just use the entityId\r\n\t\t\t// to determine the order? https://x.com/LoewenMitchell/status/1750792974383173676?s=20\r\n\t\t\t// \"It should be summoned order (which is most cases would be left to right but mid-combat that could change).\"\r\n\t\t\t// This doesn't actually work: http://replays.firestoneapp.com/?reviewId=ec5428bf-a599-4f4c-bea9-8acad5075cb8&turn=11&action=6\r\n\t\t\t// deadEntities.sort((a, b) => a.entityId - b.entityId);\r\n\t\t\t// So we would need to find another proxy for the order\r\n\t\t\tconst spawns = processDeathrattleForMinions(\r\n\t\t\t\tdeadEntities,\r\n\t\t\t\tplayerDeadEntityIndexesFromRight[i],\r\n\t\t\t\tplayerStates[i],\r\n\t\t\t\tplayerStates[1 - i],\r\n\t\t\t\tdeathrattleInput,\r\n\t\t\t\tprocessAvenge,\r\n\t\t\t);\r\n\t\t\tentitiesFromDeathrattles.push(...spawns);\r\n\t\t\t// for (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t// \tconst deadEntity = deadEntities[j];\r\n\t\t\t// \tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t// \tconst deadEntityPlayerState = playerStates[i];\r\n\t\t\t// \tconst otherPlayerState = playerStates[1 - i];\r\n\t\t\t// \tconst spawns = processDeathrattleForMinion(\r\n\t\t\t// \t\tdeadEntity,\r\n\t\t\t// \t\tindexFromRight,\r\n\t\t\t// \t\tdeadEntities,\r\n\t\t\t// \t\tdeadEntityPlayerState,\r\n\t\t\t// \t\totherPlayerState,\r\n\t\t\t// \t\tdeathrattleInput.gameState,\r\n\t\t\t// \t\tprocessAvenge,\r\n\t\t\t// \t);\r\n\t\t\t// \tentitiesFromDeathrattles.push(...spawns);\r\n\t\t\t// }\r\n\t\t}\r\n\t}\r\n\treturn entitiesFromDeathrattles;\r\n};\r\n\r\nconst processFeathermaneEffects = (deathrattleInput: DeathrattleInput, processAvenge = true): BoardEntity[] => {\r\n\tconst entitiesFromDeathrattles: BoardEntity[] = [];\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\t// Entities are processed left to right\r\n\t\t\t// TODO: in fact, the processing order is summoning order, so maybe we can just use the entityId\r\n\t\t\t// to determine the order? https://x.com/LoewenMitchell/status/1750792974383173676?s=20\r\n\t\t\t// \"It should be summoned order (which is most cases would be left to right but mid-combat that could change).\"\r\n\t\t\t// This doesn't actually work: http://replays.firestoneapp.com/?reviewId=ec5428bf-a599-4f4c-bea9-8acad5075cb8&turn=11&action=6\r\n\t\t\t// deadEntities.sort((a, b) => a.entityId - b.entityId);\r\n\t\t\t// So we would need to find another proxy for the order\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t\tconst modifiedIndexFromRight = Math.min(playerStates[i].board.length, indexFromRight);\r\n\t\t\t\tconst deadEntityPlayerState = playerStates[i];\r\n\t\t\t\tconst otherPlayerState = playerStates[1 - i];\r\n\t\t\t\tconst spawns = processFeathermaneForMinion(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\tdeadEntities,\r\n\t\t\t\t\tdeadEntityPlayerState,\r\n\t\t\t\t\totherPlayerState,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t\tprocessAvenge,\r\n\t\t\t\t);\r\n\t\t\t\tentitiesFromDeathrattles.push(...spawns);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn entitiesFromDeathrattles;\r\n};\r\n\r\nconst processFeathermaneForMinion = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n\tprocessAvenge = true,\r\n) => {\r\n\tconst maxSpawns = 7 - deadEntityPlayerState.board.length;\r\n\tconst allSpawns = [];\r\n\r\n\t// Feathermane\r\n\tif (\r\n\t\thasCorrectTribe(deadEntity, deadEntityPlayerState.player, Race.BEAST, gameState.anomalies, gameState.allCards)\r\n\t) {\r\n\t\tconst feathermanes =\r\n\t\t\tdeadEntityPlayerState.player.hand\r\n\t\t\t\t?.filter((e) => !e.locked)\r\n\t\t\t\t.filter(\r\n\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\te.cardId === CardIds.FreeFlyingFeathermane_BG27_014 ||\r\n\t\t\t\t\t\te.cardId === CardIds.FreeFlyingFeathermane_BG27_014_G,\r\n\t\t\t\t) ?? [];\r\n\t\tfor (const feathermaneSpawn of feathermanes) {\r\n\t\t\tif (allSpawns.length >= maxSpawns) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tfeathermaneSpawn.locked = true;\r\n\t\t\tconst spawns = spawnEntities(\r\n\t\t\t\tfeathermaneSpawn.cardId,\r\n\t\t\t\t1,\r\n\t\t\t\tdeadEntityPlayerState.board,\r\n\t\t\t\tdeadEntityPlayerState.player,\r\n\t\t\t\totherPlayerState.board,\r\n\t\t\t\totherPlayerState.player,\r\n\t\t\t\tgameState,\r\n\t\t\t\tdeadEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\ttrue,\r\n\t\t\t\t{ ...feathermaneSpawn } as BoardEntity,\r\n\t\t\t);\r\n\r\n\t\t\t// So that it can be flagged as \"unspawned\" if it is not spawned in the end\r\n\t\t\tfor (const spawn of spawns) {\r\n\t\t\t\tspawn.onCanceledSummon = () => (feathermaneSpawn.locked = false);\r\n\t\t\t\t// spawn.backRef = feathermaneSpawn;\r\n\t\t\t}\r\n\t\t\tallSpawns.push(...spawns);\r\n\t\t}\r\n\t}\r\n\r\n\tperformEntitySpawns(\r\n\t\tallSpawns,\r\n\t\tdeadEntityPlayerState.board,\r\n\t\tdeadEntityPlayerState.player,\r\n\t\tdeadEntity,\r\n\t\tindexFromRight,\r\n\t\totherPlayerState.board,\r\n\t\totherPlayerState.player,\r\n\t\tgameState,\r\n\t);\r\n\treturn allSpawns;\r\n};\r\n\r\nconst processDeathrattleForMinions = (\r\n\tdeadEntities: BoardEntity[],\r\n\tplayerDeadEntityIndexesFromRight: number[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tinput: DeathrattleInput,\r\n\tprocessAvenge = true,\r\n) => {\r\n\tconst entitiesFromDeathrattles: BoardEntity[] = [];\r\n\r\n\t// Natural deathrattles & enchantments\r\n\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\tconst deadEntity = deadEntities[j];\r\n\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[j];\r\n\t\tconst drEntities = handleNaturalDeathrattle(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntities,\r\n\t\t\tdeadEntityPlayerState,\r\n\t\t\totherPlayerState,\r\n\t\t\tinput.gameState,\r\n\t\t);\r\n\r\n\t\tentitiesFromDeathrattles.push(...drEntities);\r\n\t}\r\n\r\n\t// Avenge\r\n\tlet avengeEntities = [];\r\n\tif (processAvenge) {\r\n\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[j];\r\n\t\t\tavengeEntities = applyAvengeEffects(\r\n\t\t\t\tdeadEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\tdeadEntityPlayerState.board,\r\n\t\t\t\tdeadEntityPlayerState.player,\r\n\t\t\t\totherPlayerState.board,\r\n\t\t\t\totherPlayerState.player,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t\tentitiesFromDeathrattles,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\tconst allAfterDeathEntities = [];\r\n\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\tconst deadEntity = deadEntities[j];\r\n\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[j];\r\n\t\tconst afterDeathEntities = applyAfterDeathEffects(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntityPlayerState.board,\r\n\t\t\tdeadEntityPlayerState.player,\r\n\t\t\totherPlayerState.board,\r\n\t\t\totherPlayerState.player,\r\n\t\t\tinput.gameState,\r\n\t\t);\r\n\t\tallAfterDeathEntities.push(...afterDeathEntities);\r\n\t}\r\n\r\n\treturn [...entitiesFromDeathrattles, ...avengeEntities, ...allAfterDeathEntities];\r\n};\r\n\r\nexport const processDeathrattleForMinion = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n\tprocessAvenge = true,\r\n) => {\r\n\tconst drEntities = handleNaturalDeathrattle(\r\n\t\tdeadEntity,\r\n\t\tindexFromRight,\r\n\t\tdeadEntities,\r\n\t\tdeadEntityPlayerState,\r\n\t\totherPlayerState,\r\n\t\tgameState,\r\n\t);\r\n\t// Avenge trigger before reborn\r\n\t// http://replays.firestoneapp.com/?reviewId=5bb20eb8-e0ca-47ab-adc7-13134716d568&turn=7&action=6\r\n\tlet avengeEntities = [];\r\n\tlet afterDeathEntities = [];\r\n\tif (processAvenge) {\r\n\t\tavengeEntities = applyAvengeEffects(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntityPlayerState.board,\r\n\t\t\tdeadEntityPlayerState.player,\r\n\t\t\totherPlayerState.board,\r\n\t\t\totherPlayerState.player,\r\n\t\t\tgameState,\r\n\t\t\t[...drEntities],\r\n\t\t);\r\n\r\n\t\t// TODO: Feathermane should be applied after the Reborn effects have all been processed\r\n\t\t// Secrets should be processed here (\"at Avenge speed\")\r\n\t\tafterDeathEntities = applyAfterDeathEffects(\r\n\t\t\tdeadEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntityPlayerState.board,\r\n\t\t\tdeadEntityPlayerState.player,\r\n\t\t\totherPlayerState.board,\r\n\t\t\totherPlayerState.player,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n\treturn [...drEntities, ...avengeEntities, ...afterDeathEntities];\r\n};\r\n\r\nconst handleNaturalDeathrattle = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n): readonly BoardEntity[] => {\r\n\tconst modifiedIndexFromRight = Math.min(deadEntityPlayerState.board.length, indexFromRight);\r\n\t// const allSpawns = [];\r\n\t// const spawnsToSpawn = [];\r\n\tfor (const dr of deadEntity.rememberedDeathrattles ?? []) {\r\n\t\tconst entityToProcess: BoardEntity = {\r\n\t\t\t...deadEntity,\r\n\t\t\toriginalCardId: deadEntity.cardId,\r\n\t\t\trememberedDeathrattles: undefined,\r\n\t\t\tdeathrattleRepeats: dr.repeats ?? 1,\r\n\t\t\tscriptDataNum1: dr.tagScriptDataNum1,\r\n\t\t\tscriptDataNum2: dr.tagScriptDataNum2,\r\n\t\t\tcardId: dr.cardId,\r\n\t\t\tpendingAttackBuffs: [],\r\n\t\t\t// For Corrupted Bristler\r\n\t\t\tenchantments: deadEntity.enchantments.filter((e) => e.cardId?.startsWith(CardIds.BloodGem)),\r\n\t\t\tmemory:\r\n\t\t\t\tdr.memory == null\r\n\t\t\t\t\t? null\r\n\t\t\t\t\t: Array.isArray(dr.memory)\r\n\t\t\t\t\t? dr.memory.map((mem) => ({ ...mem }))\r\n\t\t\t\t\t: { ...dr.memory },\r\n\t\t};\r\n\t\tconst spawns = handleNaturalDeathrattle(\r\n\t\t\tentityToProcess,\r\n\t\t\tindexFromRight,\r\n\t\t\tdeadEntities,\r\n\t\t\tdeadEntityPlayerState,\r\n\t\t\totherPlayerState,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\t// The spawns have already been processed in the \"handleNaturalDeathrattle\" method\r\n\t\t// spawnsToSpawn.push(...spawns);\r\n\t\t// allSpawns.push(...spawns);\r\n\t}\r\n\r\n\tconst entitiesFromNativeDeathrattle: readonly BoardEntity[] = spawnEntitiesFromDeathrattle(\r\n\t\tdeadEntity,\r\n\t\tmodifiedIndexFromRight,\r\n\t\tdeadEntityPlayerState.board,\r\n\t\tdeadEntityPlayerState.player,\r\n\t\totherPlayerState.board,\r\n\t\totherPlayerState.player,\r\n\t\tdeadEntities,\r\n\t\tgameState,\r\n\t);\r\n\r\n\treturn entitiesFromNativeDeathrattle;\r\n};\r\n\r\nconst processReborns = (deathrattleInput: DeathrattleInput) => {\r\n\t// const entitiesFromReborn: BoardEntity[] = [];\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\tfor (let j = 0; j < deadEntities.length; j++) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t\tconst modifiedIndexFromRight = Math.min(playerStates[i].board.length, indexFromRight);\r\n\t\t\t\tconst deadEntityPlayerState = playerStates[i];\r\n\t\t\t\tconst otherPlayerState = playerStates[1 - i];\r\n\t\t\t\thandleRebornForEntity(\r\n\t\t\t\t\tdeadEntityPlayerState.board,\r\n\t\t\t\t\tdeadEntityPlayerState.player,\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\totherPlayerState.board,\r\n\t\t\t\t\totherPlayerState.player,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handlePostDeathrattleEffects = (deathrattleInput: DeathrattleInput, entitiesFromDeathrattles: BoardEntity[]) => {\r\n\tconst processPlayerFirst = Math.random() > 0.5;\r\n\tconst playerStates = processPlayerFirst\r\n\t\t? [deathrattleInput.gameState.gameState.player, deathrattleInput.gameState.gameState.opponent]\r\n\t\t: [deathrattleInput.gameState.gameState.opponent, deathrattleInput.gameState.gameState.player];\r\n\tconst playerDeadEntities = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntities, deathrattleInput.opponentDeadEntities]\r\n\t\t: [deathrattleInput.opponentDeadEntities, deathrattleInput.playerDeadEntities];\r\n\tconst playerDeadEntityIndexesFromRight = processPlayerFirst\r\n\t\t? [deathrattleInput.playerDeadEntityIndexesFromRight, deathrattleInput.opponentDeadEntityIndexesFromRight]\r\n\t\t: [deathrattleInput.opponentDeadEntityIndexesFromRight, deathrattleInput.playerDeadEntityIndexesFromRight];\r\n\t// Process one player first, then the other\r\n\tfor (let i = 0; i < 2; i++) {\r\n\t\tconst deadEntities = playerDeadEntities[i];\r\n\t\tconst deadEntityPlayerState = playerStates[i];\r\n\t\tconst otherPlayerState = playerStates[1 - i];\r\n\t\tif (deadEntities.length >= 0) {\r\n\t\t\t// Process from right to left, so that we can set the hasAttacked attribute properly\r\n\t\t\t// If two minions die at the same time, both of which having attacked, but the third in line having not,\r\n\t\t\t// processing them from left to right means the first (leftmost) one will check its right neighbor, which\r\n\t\t\t// is the minion that hasn't attacked\r\n\t\t\tfor (let j = deadEntities.length - 1; j >= 0; j--) {\r\n\t\t\t\tconst deadEntity = deadEntities[j];\r\n\t\t\t\tconst indexFromRight = playerDeadEntityIndexesFromRight[i][j];\r\n\t\t\t\tconst modifiedIndexFromRight = Math.min(playerStates[i].board.length, indexFromRight);\r\n\t\t\t\thandlePostDeathrattleEffect(\r\n\t\t\t\t\tdeadEntity,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\tdeadEntities,\r\n\t\t\t\t\tdeadEntityPlayerState,\r\n\t\t\t\t\totherPlayerState,\r\n\t\t\t\t\tdeathrattleInput.gameState,\r\n\t\t\t\t\tentitiesFromDeathrattles,\r\n\t\t\t\t\tdeadEntityPlayerState.player.friendly,\r\n\t\t\t\t\tdeathrattleInput,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const handleDeathrattles = (deathrattleInput: DeathrattleInput) => {\r\n\torchestrateMinionDeathEffects(deathrattleInput, false, false);\r\n};\r\n\r\nconst handlePostDeathrattleEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tdeadEntities: BoardEntity[],\r\n\tdeadEntityPlayerState: PlayerState,\r\n\totherPlayerState: PlayerState,\r\n\tgameState: FullGameState,\r\n\tspawnedEntities: BoardEntity[],\r\n\tisPlayer: boolean,\r\n\tdeathrattleInput: DeathrattleInput,\r\n) => {\r\n\t// This doesn't work if the entity that was to the right died.\r\n\tconst entityRightToSpawns =\r\n\t\tindexFromRight === 0 ? null : deadEntityPlayerState.board[deadEntityPlayerState.board.length - indexFromRight];\r\n\t// To handle minions attack tokens\r\n\t// See http://replays.firestoneapp.com/?reviewId=0583d6a4-6ed0-4b20-894e-4ceb560894fe&turn=6&action=11\r\n\t// When a minion dies, the spawn are either elligible to attack next turn or not\r\n\t// If the minion right to the spawned minion has already attacked, then the spawned\r\n\t// minion cannot attack\r\n\tspawnedEntities.forEach((entity) => {\r\n\t\tentity.hasAttacked =\r\n\t\t\tentity.hasAttacked || (deadEntity.hasAttacked > 1 ? 1 : entityRightToSpawns?.hasAttacked ?? undefined);\r\n\t});\r\n\r\n\tif (deadEntityPlayerState.player.questRewards?.includes(CardIds.RitualDagger_BG24_Reward_113)) {\r\n\t\tconst ogDeadEntity = gameState.sharedState.deaths.find((entity) => entity.entityId === deadEntity.entityId);\r\n\t\tif (ogDeadEntity) {\r\n\t\t\togDeadEntity.attack += 4;\r\n\t\t\togDeadEntity.health += 4;\r\n\t\t}\r\n\t}\r\n\r\n\t// ISSUE: when we do this, we change the minion's stats before processing deathrattle effects, which can mess\r\n\t// up the simulation in some cases (like Nightbane, Ignited)\r\n\t// FIX: we do it in postDeathrattleEfects, not when removing minions from the board\r\n\tif (deadEntityPlayerState.player.globalInfo.HauntedCarapaceAttackBonus > 0) {\r\n\t\tdeadEntity.attack = Math.max(\r\n\t\t\t0,\r\n\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.HauntedCarapaceAttackBonus,\r\n\t\t);\r\n\t}\r\n\tif (deadEntityPlayerState.player.globalInfo.HauntedCarapaceHealthBonus > 0) {\r\n\t\tdeadEntity.health = Math.max(\r\n\t\t\t1,\r\n\t\t\tdeadEntity.health - deadEntityPlayerState.player.globalInfo.HauntedCarapaceHealthBonus,\r\n\t\t);\r\n\t}\r\n\tif (\r\n\t\thasCorrectTribe(deadEntity, deadEntityPlayerState.player, Race.UNDEAD, gameState.anomalies, gameState.allCards)\r\n\t) {\r\n\t\tif (deadEntityPlayerState.player.globalInfo.UndeadAttackBonus > 0) {\r\n\t\t\tdeadEntity.attack = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.UndeadAttackBonus,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (deadEntityPlayerState.player.globalInfo.UndeadHealthBonus > 0) {\r\n\t\t\tdeadEntity.health = Math.max(\r\n\t\t\t\t1,\r\n\t\t\t\tdeadEntity.health - deadEntityPlayerState.player.globalInfo.UndeadHealthBonus,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\tif (\r\n\t\thasCorrectTribe(deadEntity, deadEntityPlayerState.player, Race.BEAST, gameState.anomalies, gameState.allCards)\r\n\t) {\r\n\t\tif (deadEntityPlayerState.player.globalInfo.GoldrinnBuffAtk > 0) {\r\n\t\t\tdeadEntity.attack = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.GoldrinnBuffAtk,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\tif (isWhelp(deadEntity.cardId, gameState.allCards)) {\r\n\t\tif (deadEntityPlayerState.player.globalInfo.WhelpAttackBuff > 0) {\r\n\t\t\tdeadEntity.attack = Math.max(\r\n\t\t\t\t0,\r\n\t\t\t\tdeadEntity.attack - deadEntityPlayerState.player.globalInfo.WhelpAttackBuff,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n};\r\n\r\ninterface DeathrattleInput {\r\n\tgameState: FullGameState;\r\n\tplayerDeadEntities: BoardEntity[];\r\n\tplayerDeadEntityIndexesFromRight: number[];\r\n\topponentDeadEntities: BoardEntity[];\r\n\topponentDeadEntityIndexesFromRight: number[];\r\n}\r\n"]}
@@ -43,7 +43,11 @@ const makeMinionsDie = (board, boardHero, otherBoard, otherBoardHero, gameState)
43
43
  (0, exports.onMinionDeadQuest)(deadEntity, indexFromRight, board, boardHero, otherBoard, otherBoardHero, gameState);
44
44
  (0, exports.onMinionDeadQuest)(deadEntity, indexFromRight, otherBoard, otherBoardHero, board, boardHero, gameState);
45
45
  }
46
- return [deadMinionIndexesFromLeft, indexesFromRightAfterDeath, deadEntities];
46
+ return [
47
+ deadMinionIndexesFromLeft,
48
+ indexesFromRightAfterDeath,
49
+ deadEntities,
50
+ ];
47
51
  };
48
52
  exports.makeMinionsDie = makeMinionsDie;
49
53
  const onMinionDeadHeroPower = (board, boardHero, deadEntity, gameState) => {
@@ -1 +1 @@
1
- {"version":3,"file":"minion-death.js","sourceRoot":"","sources":["../../src/simulation/minion-death.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { applyRunicEmpowermentOnFriendlyDeath } from '../cards/impl/hero-power/runic-empowerment';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickMultipleRandomAlive } from '../services/utils';\r\nimport { getEffectiveTribesForEntity } from '../utils';\r\nimport { updateAvengeCounters } from './avenge';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { handleWheneverMinionsKillEffect } from './deathrattle-effects';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { onQuestProgressUpdated } from './quest';\r\nimport { removeMinionFromBoard } from './remove-minion-from-board';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const makeMinionsDie = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): [number[], number[], BoardEntity[]] => {\r\n\t// Because entities spawn to the left, so the right index is unchanged\r\n\tconst deadMinionIndexesFromLeft: number[] = [];\r\n\tconst deadMinionIndexesFromRight: number[] = [];\r\n\tconst deadEntities: BoardEntity[] = [];\r\n\tconst initialBoardLength = board.length;\r\n\r\n\thandleWheneverMinionsKillEffect(board, boardHero, otherBoard, otherBoardHero, gameState);\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].health <= 0 || board[i].definitelyDead) {\r\n\t\t\tdeadMinionIndexesFromLeft.push(i);\r\n\t\t\tdeadMinionIndexesFromRight.push(initialBoardLength - (i + 1));\r\n\t\t\tdeadEntities.push(board[i]);\r\n\t\t\t// console.log(\r\n\t\t\t// \t'\\tflagging dead minion 0',\r\n\t\t\t// \tstringifySimpleCard(board[i], allCards),\r\n\t\t\t// \tstringifySimple(board, allCards),\r\n\t\t\t// \tinitialBoardLength,\r\n\t\t\t// \ti,\r\n\t\t\t// \tdeadMinionIndexesFromRight,\r\n\t\t\t// );\r\n\t\t}\r\n\t}\r\n\r\n\t// These will always be processed from left to right afterwards\r\n\t// We compute the indexes as they will be once the new board is effective. For a\r\n\t// board of length N, having an indexFromRight at N means it will spawn at the very left\r\n\t// of the board (first minion)\r\n\tlet indexesFromRightAfterDeath = [];\r\n\tfor (let i = deadMinionIndexesFromRight.length - 1; i >= 0; i--) {\r\n\t\tconst newIndex = deadMinionIndexesFromRight[i] - indexesFromRightAfterDeath.length;\r\n\t\tindexesFromRightAfterDeath.push(newIndex);\r\n\t}\r\n\tindexesFromRightAfterDeath = indexesFromRightAfterDeath.reverse();\r\n\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].health <= 0 || board[i].definitelyDead) {\r\n\t\t\t// console.log('\\tflagging dead minion', stringifySimpleCard(board[i], allCards), deadMinionIndexesFromRight);\r\n\t\t\tremoveMinionFromBoard(board, boardHero, i, gameState);\r\n\t\t\t// We modify the original array, so we need to update teh current index accordingly\r\n\t\t\ti--;\r\n\t\t}\r\n\t}\r\n\r\n\t// console.debug('dead entities', stringifySimple(deadEntities, allCards));\r\n\t// Update the avenge counters as soon as minions die. If we wait until the \"avenge\" phase, we might\r\n\t// update the counters for entities that have been spawned after the death of the original entity\r\n\t// ISSUE: deaths are actually processed one by one. Once a minion dies, its DR triggers, then the next, etc.\r\n\t// This means that if you have a minion that summons another one, it can progress and complete and quest\r\n\t// and the next minion dying could count towards that quest progress\r\n\t// See http://replays.firestoneapp.com/?reviewId=0ce4db9c-3269-4704-b662-8a8c31f5afe1&turn=16&action=27\r\n\tfor (const deadEntity of deadEntities) {\r\n\t\tconst indexFromRight = indexesFromRightAfterDeath[deadEntities.indexOf(deadEntity)];\r\n\t\tupdateAvengeCounters(board, boardHero);\r\n\t\tonMinionDeadHeroPower(board, boardHero, deadEntity, gameState);\r\n\t\tonMinionDeadHeroPower(otherBoard, otherBoardHero, deadEntity, gameState);\r\n\t\tonMinionDeadQuest(deadEntity, indexFromRight, board, boardHero, otherBoard, otherBoardHero, gameState);\r\n\t\tonMinionDeadQuest(deadEntity, indexFromRight, otherBoard, otherBoardHero, board, boardHero, gameState);\r\n\t}\r\n\r\n\treturn [deadMinionIndexesFromLeft, indexesFromRightAfterDeath, deadEntities];\r\n};\r\n\r\nexport const onMinionDeadHeroPower = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tfor (const heroPower of boardHero.heroPowers) {\r\n\t\tif (\r\n\t\t\theroPower.cardId === CardIds.IllTakeThat &&\r\n\t\t\theroPower.used &&\r\n\t\t\theroPower.info2 <= 0 &&\r\n\t\t\tdeadEntity.friendly !== boardHero.friendly\r\n\t\t) {\r\n\t\t\taddCardsInHand(boardHero, board, [deadEntity.cardId], gameState);\r\n\t\t\theroPower.info2 = 1;\r\n\t\t}\r\n\t\tapplyRunicEmpowermentOnFriendlyDeath(heroPower, boardHero, deadEntity);\r\n\t}\r\n};\r\n\r\nexport const onMinionDeadQuest = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst quests = boardHero.questEntities ?? [];\r\n\tfor (const quest of quests) {\r\n\t\tswitch (quest.CardId) {\r\n\t\t\tcase CardIds.ReenactTheMurder:\r\n\t\t\t\tif (deadEntity.friendly === boardHero.friendly) {\r\n\t\t\t\t\tonQuestProgressUpdated(boardHero, quest, board, gameState);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.RoundUpTheSuspects:\r\n\t\t\t\tif (deadEntity.friendly !== boardHero.friendly) {\r\n\t\t\t\t\tonQuestProgressUpdated(boardHero, quest, board, gameState);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tfor (const trinket of boardHero.trinkets) {\r\n\t\tswitch (trinket.cardId) {\r\n\t\t\tcase CardIds.AllianceKeychain_BG30_MagicItem_433:\r\n\t\t\tcase CardIds.AllianceKeychain_AllianceKeychainToken_BG30_MagicItem_433t:\r\n\t\t\t\tif (trinket.scriptDataNum1 > 0 && deadEntity.friendly === boardHero.friendly) {\r\n\t\t\t\t\tconst quantity = trinket.cardId === CardIds.AllianceKeychain_BG30_MagicItem_433 ? 1 : 2;\r\n\t\t\t\t\tconst targets = pickMultipleRandomAlive(board, quantity);\r\n\t\t\t\t\tfor (const target of targets) {\r\n\t\t\t\t\t\tmodifyStats(\r\n\t\t\t\t\t\t\ttarget,\r\n\t\t\t\t\t\t\tboardHero,\r\n\t\t\t\t\t\t\tdeadEntity.maxAttack,\r\n\t\t\t\t\t\t\tdeadEntity.maxHealth,\r\n\t\t\t\t\t\t\tboard,\r\n\t\t\t\t\t\t\tboardHero,\r\n\t\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttrinket.scriptDataNum1--;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.TheEyeOfDalaran_BG30_MagicItem_981:\r\n\t\t\t\tif (\r\n\t\t\t\t\tdeadEntity.friendly === boardHero.friendly &&\r\n\t\t\t\t\tgetEffectiveTribesForEntity(deadEntity, boardHero, gameState.anomalies, gameState.allCards)\r\n\t\t\t\t\t\t.length === 0\r\n\t\t\t\t) {\r\n\t\t\t\t\taddCardsInHand(boardHero, board, [null], gameState);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n};\r\n"]}
1
+ {"version":3,"file":"minion-death.js","sourceRoot":"","sources":["../../src/simulation/minion-death.ts"],"names":[],"mappings":";;;AAEA,kFAAkG;AAElG,6CAA4D;AAC5D,oCAAuD;AACvD,qCAAgD;AAChD,mDAAiD;AACjD,+DAAwE;AAExE,mCAAiD;AACjD,yEAAmE;AACnE,mCAAsC;AAE/B,MAAM,cAAc,GAAG,CAC7B,KAAoB,EACpB,SAA0B,EAC1B,UAAyB,EACzB,cAA+B,EAC/B,SAAwB,EACc,EAAE;IAExC,MAAM,yBAAyB,GAAa,EAAE,CAAC;IAC/C,MAAM,0BAA0B,GAAa,EAAE,CAAC;IAChD,MAAM,YAAY,GAAkB,EAAE,CAAC;IACvC,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAC;IAExC,IAAA,qDAA+B,EAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;IACzF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE;YACpD,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClC,0BAA0B,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC9D,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;SAS5B;KACD;IAMD,IAAI,0BAA0B,GAAG,EAAE,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,0BAA0B,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QAChE,MAAM,QAAQ,GAAG,0BAA0B,CAAC,CAAC,CAAC,GAAG,0BAA0B,CAAC,MAAM,CAAC;QACnF,0BAA0B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KAC1C;IACD,0BAA0B,GAAG,0BAA0B,CAAC,OAAO,EAAE,CAAC;IAElE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE;YAEpD,IAAA,gDAAqB,EAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;YAEtD,CAAC,EAAE,CAAC;SACJ;KACD;IASD,KAAK,MAAM,UAAU,IAAI,YAAY,EAAE;QACtC,MAAM,cAAc,GAAG,0BAA0B,CAAC,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,IAAA,6BAAoB,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACvC,IAAA,6BAAqB,EAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/D,IAAA,6BAAqB,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QACzE,IAAA,yBAAiB,EAAC,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;QACvG,IAAA,yBAAiB,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;KACvG;IAED,OAAO;QACN,yBAAyB;QACzB,0BAA0B;QAM1B,YAAY;KACZ,CAAC;AACH,CAAC,CAAC;AA5EW,QAAA,cAAc,kBA4EzB;AAEK,MAAM,qBAAqB,GAAG,CACpC,KAAoB,EACpB,SAA0B,EAC1B,UAAuB,EACvB,SAAwB,EACvB,EAAE;IACH,KAAK,MAAM,SAAS,IAAI,SAAS,CAAC,UAAU,EAAE;QAC7C,IACC,SAAS,CAAC,MAAM,0BAAwB;YACxC,SAAS,CAAC,IAAI;YACd,SAAS,CAAC,KAAK,IAAI,CAAC;YACpB,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,EACzC;YACD,IAAA,8BAAc,EAAC,SAAS,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;YACjE,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC;SACpB;QACD,IAAA,wDAAoC,EAAC,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;KACvE;AACF,CAAC,CAAC;AAlBW,QAAA,qBAAqB,yBAkBhC;AAEK,MAAM,iBAAiB,GAAG,CAChC,UAAuB,EACvB,cAAsB,EACtB,KAAoB,EACpB,SAA0B,EAC1B,UAAyB,EACzB,cAA+B,EAC/B,SAAwB,EACvB,EAAE;;IACH,MAAM,MAAM,GAAG,MAAA,SAAS,CAAC,aAAa,mCAAI,EAAE,CAAC;IAC7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;QAC3B,QAAQ,KAAK,CAAC,MAAM,EAAE;YACrB;gBACC,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,EAAE;oBAC/C,IAAA,8BAAsB,EAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;iBAC3D;gBACD,MAAM;YACP;gBACC,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,EAAE;oBAC/C,IAAA,8BAAsB,EAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;iBAC3D;gBACD,MAAM;SACP;KACD;IAED,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE;QACzC,QAAQ,OAAO,CAAC,MAAM,EAAE;YACvB,0BAAiD;YACjD;gBACC,IAAI,OAAO,CAAC,cAAc,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ,EAAE;oBAC7E,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,yBAAgD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACxF,MAAM,OAAO,GAAG,IAAA,+BAAuB,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;oBACzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;wBAC7B,IAAA,mBAAW,EACV,MAAM,EACN,SAAS,EACT,UAAU,CAAC,SAAS,EACpB,UAAU,CAAC,SAAS,EACpB,KAAK,EACL,SAAS,EACT,SAAS,CACT,CAAC;qBACF;oBACD,OAAO,CAAC,cAAc,EAAE,CAAC;iBACzB;gBACD,MAAM;YACP;gBACC,IACC,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ;oBAC1C,IAAA,mCAA2B,EAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC;yBACzF,MAAM,KAAK,CAAC,EACb;oBACD,IAAA,8BAAc,EAAC,SAAS,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;iBACpD;gBACD,MAAM;SACP;KACD;AACF,CAAC,CAAC;AAzDW,QAAA,iBAAiB,qBAyD5B","sourcesContent":["import { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { applyRunicEmpowermentOnFriendlyDeath } from '../cards/impl/hero-power/runic-empowerment';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickMultipleRandomAlive } from '../services/utils';\r\nimport { getEffectiveTribesForEntity } from '../utils';\r\nimport { updateAvengeCounters } from './avenge';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { handleWheneverMinionsKillEffect } from './deathrattle-effects';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { onQuestProgressUpdated } from './quest';\r\nimport { removeMinionFromBoard } from './remove-minion-from-board';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const makeMinionsDie = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): [number[], number[], BoardEntity[]] => {\r\n\t// Because entities spawn to the left, so the right index is unchanged\r\n\tconst deadMinionIndexesFromLeft: number[] = [];\r\n\tconst deadMinionIndexesFromRight: number[] = [];\r\n\tconst deadEntities: BoardEntity[] = [];\r\n\tconst initialBoardLength = board.length;\r\n\r\n\thandleWheneverMinionsKillEffect(board, boardHero, otherBoard, otherBoardHero, gameState);\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].health <= 0 || board[i].definitelyDead) {\r\n\t\t\tdeadMinionIndexesFromLeft.push(i);\r\n\t\t\tdeadMinionIndexesFromRight.push(initialBoardLength - (i + 1));\r\n\t\t\tdeadEntities.push(board[i]);\r\n\t\t\t// console.log(\r\n\t\t\t// \t'\\tflagging dead minion 0',\r\n\t\t\t// \tstringifySimpleCard(board[i], allCards),\r\n\t\t\t// \tstringifySimple(board, allCards),\r\n\t\t\t// \tinitialBoardLength,\r\n\t\t\t// \ti,\r\n\t\t\t// \tdeadMinionIndexesFromRight,\r\n\t\t\t// );\r\n\t\t}\r\n\t}\r\n\r\n\t// These will always be processed from left to right afterwards\r\n\t// We compute the indexes as they will be once the new board is effective. For a\r\n\t// board of length N, having an indexFromRight at N means it will spawn at the very left\r\n\t// of the board (first minion)\r\n\tlet indexesFromRightAfterDeath = [];\r\n\tfor (let i = deadMinionIndexesFromRight.length - 1; i >= 0; i--) {\r\n\t\tconst newIndex = deadMinionIndexesFromRight[i] - indexesFromRightAfterDeath.length;\r\n\t\tindexesFromRightAfterDeath.push(newIndex);\r\n\t}\r\n\tindexesFromRightAfterDeath = indexesFromRightAfterDeath.reverse();\r\n\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].health <= 0 || board[i].definitelyDead) {\r\n\t\t\t// console.log('\\tflagging dead minion', stringifySimpleCard(board[i], allCards), deadMinionIndexesFromRight);\r\n\t\t\tremoveMinionFromBoard(board, boardHero, i, gameState);\r\n\t\t\t// We modify the original array, so we need to update teh current index accordingly\r\n\t\t\ti--;\r\n\t\t}\r\n\t}\r\n\r\n\t// console.debug('dead entities', stringifySimple(deadEntities, allCards));\r\n\t// Update the avenge counters as soon as minions die. If we wait until the \"avenge\" phase, we might\r\n\t// update the counters for entities that have been spawned after the death of the original entity\r\n\t// ISSUE: deaths are actually processed one by one. Once a minion dies, its DR triggers, then the next, etc.\r\n\t// This means that if you have a minion that summons another one, it can progress and complete and quest\r\n\t// and the next minion dying could count towards that quest progress\r\n\t// See http://replays.firestoneapp.com/?reviewId=0ce4db9c-3269-4704-b662-8a8c31f5afe1&turn=16&action=27\r\n\tfor (const deadEntity of deadEntities) {\r\n\t\tconst indexFromRight = indexesFromRightAfterDeath[deadEntities.indexOf(deadEntity)];\r\n\t\tupdateAvengeCounters(board, boardHero);\r\n\t\tonMinionDeadHeroPower(board, boardHero, deadEntity, gameState);\r\n\t\tonMinionDeadHeroPower(otherBoard, otherBoardHero, deadEntity, gameState);\r\n\t\tonMinionDeadQuest(deadEntity, indexFromRight, board, boardHero, otherBoard, otherBoardHero, gameState);\r\n\t\tonMinionDeadQuest(deadEntity, indexFromRight, otherBoard, otherBoardHero, board, boardHero, gameState);\r\n\t}\r\n\r\n\treturn [\r\n\t\tdeadMinionIndexesFromLeft,\r\n\t\tindexesFromRightAfterDeath,\r\n\t\t// 2026-09-28: https://replays.firestoneapp.com/?reviewId=6508654f-9f46-47ba-a1e5-6b73566c4d46&turn=9&action=2&debug=true\r\n\t\t// Not always left to right apparently\r\n\t\t// If so, this is an issue, because when we get the opponent's board, we get the entity IDs orderer from\r\n\t\t// left to right, so we lose that information\r\n\t\t// deadEntities.sort((a, b) => a.entityId - b.entityId),\r\n\t\tdeadEntities,\r\n\t];\r\n};\r\n\r\nexport const onMinionDeadHeroPower = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tfor (const heroPower of boardHero.heroPowers) {\r\n\t\tif (\r\n\t\t\theroPower.cardId === CardIds.IllTakeThat &&\r\n\t\t\theroPower.used &&\r\n\t\t\theroPower.info2 <= 0 &&\r\n\t\t\tdeadEntity.friendly !== boardHero.friendly\r\n\t\t) {\r\n\t\t\taddCardsInHand(boardHero, board, [deadEntity.cardId], gameState);\r\n\t\t\theroPower.info2 = 1;\r\n\t\t}\r\n\t\tapplyRunicEmpowermentOnFriendlyDeath(heroPower, boardHero, deadEntity);\r\n\t}\r\n};\r\n\r\nexport const onMinionDeadQuest = (\r\n\tdeadEntity: BoardEntity,\r\n\tindexFromRight: number,\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst quests = boardHero.questEntities ?? [];\r\n\tfor (const quest of quests) {\r\n\t\tswitch (quest.CardId) {\r\n\t\t\tcase CardIds.ReenactTheMurder:\r\n\t\t\t\tif (deadEntity.friendly === boardHero.friendly) {\r\n\t\t\t\t\tonQuestProgressUpdated(boardHero, quest, board, gameState);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.RoundUpTheSuspects:\r\n\t\t\t\tif (deadEntity.friendly !== boardHero.friendly) {\r\n\t\t\t\t\tonQuestProgressUpdated(boardHero, quest, board, gameState);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tfor (const trinket of boardHero.trinkets) {\r\n\t\tswitch (trinket.cardId) {\r\n\t\t\tcase CardIds.AllianceKeychain_BG30_MagicItem_433:\r\n\t\t\tcase CardIds.AllianceKeychain_AllianceKeychainToken_BG30_MagicItem_433t:\r\n\t\t\t\tif (trinket.scriptDataNum1 > 0 && deadEntity.friendly === boardHero.friendly) {\r\n\t\t\t\t\tconst quantity = trinket.cardId === CardIds.AllianceKeychain_BG30_MagicItem_433 ? 1 : 2;\r\n\t\t\t\t\tconst targets = pickMultipleRandomAlive(board, quantity);\r\n\t\t\t\t\tfor (const target of targets) {\r\n\t\t\t\t\t\tmodifyStats(\r\n\t\t\t\t\t\t\ttarget,\r\n\t\t\t\t\t\t\tboardHero,\r\n\t\t\t\t\t\t\tdeadEntity.maxAttack,\r\n\t\t\t\t\t\t\tdeadEntity.maxHealth,\r\n\t\t\t\t\t\t\tboard,\r\n\t\t\t\t\t\t\tboardHero,\r\n\t\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttrinket.scriptDataNum1--;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.TheEyeOfDalaran_BG30_MagicItem_981:\r\n\t\t\t\tif (\r\n\t\t\t\t\tdeadEntity.friendly === boardHero.friendly &&\r\n\t\t\t\t\tgetEffectiveTribesForEntity(deadEntity, boardHero, gameState.anomalies, gameState.allCards)\r\n\t\t\t\t\t\t.length === 0\r\n\t\t\t\t) {\r\n\t\t\t\t\taddCardsInHand(boardHero, board, [null], gameState);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n};\r\n"]}
@@ -6,12 +6,12 @@ const debug_state_1 = require("../debug-state");
6
6
  const utils_1 = require("../utils");
7
7
  const attack_1 = require("./attack");
8
8
  const auras_1 = require("./auras");
9
+ const combat_profile_1 = require("./combat-profile");
9
10
  const damage_cap_1 = require("./damage-cap");
10
11
  const pending_effects_1 = require("./pending-effects");
11
12
  const secrets_1 = require("./secrets");
12
13
  const start_of_combat_1 = require("./start-of-combat/start-of-combat");
13
14
  const summon_when_space_1 = require("./summon-when-space");
14
- const combat_profile_1 = require("./combat-profile");
15
15
  class Simulator {
16
16
  constructor(gameState) {
17
17
  this.gameState = gameState;
@@ -134,9 +134,7 @@ class Simulator {
134
134
  additionalCards: e.additionalCards ? [...e.additionalCards] : e.additionalCards,
135
135
  });
136
136
  });
137
- const snapshotSecrets = (secrets) => (secrets !== null && secrets !== void 0 ? secrets : [])
138
- .filter((s) => !s.triggered)
139
- .map((s) => ({ ...s }));
137
+ const snapshotSecrets = (secrets) => (secrets !== null && secrets !== void 0 ? secrets : []).filter((s) => !s.triggered).map((s) => ({ ...s }));
140
138
  const snapshotTrinkets = (trinkets) => (trinkets !== null && trinkets !== void 0 ? trinkets : []).map((t) => ({ ...t }));
141
139
  const snapshotHeroPowers = (hps) => (hps !== null && hps !== void 0 ? hps : []).map((hp) => ({ ...hp }));
142
140
  const packed = {
@@ -183,9 +181,7 @@ class Simulator {
183
181
  const losingHero = playerEntity !== null && playerEntity !== void 0 ? playerEntity : playerState.player;
184
182
  let damage = this.capDamage(this.buildBoardTotalDamage(opponentBoard, (_j = (_h = this.gameState.gameState.opponent) === null || _h === void 0 ? void 0 : _h.teammate) === null || _j === void 0 ? void 0 : _j.board) +
185
183
  ((_k = winningHero === null || winningHero === void 0 ? void 0 : winningHero.tavernTier) !== null && _k !== void 0 ? _k : 1));
186
- if (this.gameState.applyIceBlock &&
187
- damage > 0 &&
188
- (0, secrets_1.tryPreventCombatDamageWithIceBlock)(losingHero)) {
184
+ if (this.gameState.applyIceBlock && damage > 0 && (0, secrets_1.tryPreventCombatDamageWithIceBlock)(losingHero)) {
189
185
  damage = 0;
190
186
  }
191
187
  this.gameState.spectator.registerOpponentAttack(playerBoard, opponentBoard, damage);
@@ -200,9 +196,7 @@ class Simulator {
200
196
  const losingHero = opponentEntity !== null && opponentEntity !== void 0 ? opponentEntity : opponentState.player;
201
197
  let damage = this.capDamage(this.buildBoardTotalDamage(playerBoard, (_m = (_l = this.gameState.gameState.player) === null || _l === void 0 ? void 0 : _l.teammate) === null || _m === void 0 ? void 0 : _m.board) +
202
198
  ((_o = winningHero === null || winningHero === void 0 ? void 0 : winningHero.tavernTier) !== null && _o !== void 0 ? _o : 1));
203
- if (this.gameState.applyIceBlock &&
204
- damage > 0 &&
205
- (0, secrets_1.tryPreventCombatDamageWithIceBlock)(losingHero)) {
199
+ if (this.gameState.applyIceBlock && damage > 0 && (0, secrets_1.tryPreventCombatDamageWithIceBlock)(losingHero)) {
206
200
  damage = 0;
207
201
  }
208
202
  this.gameState.spectator.registerPlayerAttack(playerBoard, opponentBoard, damage);
@@ -257,7 +251,6 @@ class Simulator {
257
251
  opponentBoard.length > 0 &&
258
252
  playerEntity.hpLeft > 0 &&
259
253
  opponentEntity.hpLeft > 0) {
260
- (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);
261
254
  (0, auras_1.clearStealthIfNeeded)(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);
262
255
  if (playerBoard.some((entity) => entity.attackImmediately)) {
263
256
  this.currentSpeedAttacker = 0;
@@ -295,6 +288,7 @@ class Simulator {
295
288
  this.hasShowShortCircuitWarning = true;
296
289
  break;
297
290
  }
291
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);
298
292
  }
299
293
  if (profile) {
300
294
  (0, combat_profile_1.combatProfileAdd)('socMs', socMs);
@@ -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 { tryPreventCombatDamageWithIceBlock } from './secrets';\r\nimport { handleStartOfCombat } from './start-of-combat/start-of-combat';\r\nimport { handleSummonsWhenSpace } from './summon-when-space';\r\nimport { combatProfileAdd, combatProfileEnabled } from './combat-profile';\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\tplayerEntity.globalInfo = playerEntity.globalInfo ?? {};\r\n\t\topponentEntity.globalInfo = opponentEntity.globalInfo ?? {};\r\n\t\tplayerEntity.globalInfo.RallyMinionAttacksThisCombat = 0;\r\n\t\topponentEntity.globalInfo.RallyMinionAttacksThisCombat = 0;\r\n\t\tplayerEntity.globalInfo.FreeRefreshesGainedThisCombat = 0;\r\n\t\topponentEntity.globalInfo.FreeRefreshesGainedThisCombat = 0;\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\tconst snapshotBoard = (board: BoardEntity[] | null | undefined): BoardEntity[] =>\r\n\t\t\t(board ?? []).map((e) => ({\r\n\t\t\t\t...e,\r\n\t\t\t\tenchantments: [...(e.enchantments ?? [])],\r\n\t\t\t\tpendingAttackBuffs: [...(e.pendingAttackBuffs ?? [])],\r\n\t\t\t\tadditionalCards: e.additionalCards ? [...e.additionalCards] : e.additionalCards,\r\n\t\t\t}));\r\n\r\n\t\tconst snapshotQuests = (hero: BgsPlayerEntity | null | undefined) => ({\r\n\t\t\tquestEntities: (hero?.questEntities ?? []).map((q) => ({ ...q })),\r\n\t\t\tquestRewards: [...(hero?.questRewards ?? [])],\r\n\t\t\tquestRewardEntities: (hero?.questRewardEntities ?? []).map((r) => ({ ...r })),\r\n\t\t});\r\n\r\n\t\tconst withQuestWriteback = (\r\n\t\t\tbase: Omit<\r\n\t\t\t\tSingleSimulationResult,\r\n\t\t\t\t| 'playerQuestEntities'\r\n\t\t\t\t| 'playerQuestRewards'\r\n\t\t\t\t| 'playerQuestRewardEntities'\r\n\t\t\t\t| 'opponentQuestEntities'\r\n\t\t\t\t| 'opponentQuestRewards'\r\n\t\t\t\t| 'opponentQuestRewardEntities'\r\n\t\t\t\t| 'playerRallyAttacksThisCombat'\r\n\t\t\t\t| 'opponentRallyAttacksThisCombat'\r\n\t\t\t\t| 'playerFreeRefreshesGainedThisCombat'\r\n\t\t\t\t| 'opponentFreeRefreshesGainedThisCombat'\r\n\t\t\t\t| 'playerFodderRefreshes'\r\n\t\t\t\t| 'opponentFodderRefreshes'\r\n\t\t\t\t| 'playerGlobalInfo'\r\n\t\t\t\t| 'opponentGlobalInfo'\r\n\t\t\t\t| 'playerHand'\r\n\t\t\t\t| 'opponentHand'\r\n\t\t\t\t| 'playerSecrets'\r\n\t\t\t\t| 'opponentSecrets'\r\n\t\t\t\t| 'playerTrinkets'\r\n\t\t\t\t| 'opponentTrinkets'\r\n\t\t\t\t| 'playerHeroPowers'\r\n\t\t\t\t| 'opponentHeroPowers'\r\n\t\t\t>,\r\n\t\t): SingleSimulationResult => {\r\n\t\t\tconst t0 = combatProfileEnabled() ? performance.now() : 0;\r\n\t\t\tconst playerQ = snapshotQuests(playerEntity);\r\n\t\t\tconst opponentQ = snapshotQuests(opponentEntity);\r\n\t\t\tconst snapshotHand = (hand: typeof playerEntity.hand) =>\r\n\t\t\t\t(hand ?? []).map((e) => ({\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\tenchantments: [...(e.enchantments ?? [])],\r\n\t\t\t\t\tadditionalCards: e.additionalCards ? [...e.additionalCards] : e.additionalCards,\r\n\t\t\t\t}));\r\n\t\t\tconst snapshotSecrets = (secrets: typeof playerEntity.secrets) =>\r\n\t\t\t\t(secrets ?? [])\r\n\t\t\t\t\t.filter((s) => !s.triggered)\r\n\t\t\t\t\t.map((s) => ({ ...s }));\r\n\t\t\tconst snapshotTrinkets = (trinkets: typeof playerEntity.trinkets) =>\r\n\t\t\t\t(trinkets ?? []).map((t) => ({ ...t }));\r\n\t\t\tconst snapshotHeroPowers = (hps: typeof playerEntity.heroPowers) =>\r\n\t\t\t\t(hps ?? []).map((hp) => ({ ...hp }));\r\n\t\t\tconst packed: SingleSimulationResult = {\r\n\t\t\t\t...base,\r\n\t\t\t\tplayerQuestEntities: playerQ.questEntities,\r\n\t\t\t\tplayerQuestRewards: playerQ.questRewards,\r\n\t\t\t\tplayerQuestRewardEntities: playerQ.questRewardEntities,\r\n\t\t\t\topponentQuestEntities: opponentQ.questEntities,\r\n\t\t\t\topponentQuestRewards: opponentQ.questRewards,\r\n\t\t\t\topponentQuestRewardEntities: opponentQ.questRewardEntities,\r\n\t\t\t\tplayerRallyAttacksThisCombat: playerEntity?.globalInfo?.RallyMinionAttacksThisCombat ?? 0,\r\n\t\t\t\topponentRallyAttacksThisCombat: opponentEntity?.globalInfo?.RallyMinionAttacksThisCombat ?? 0,\r\n\t\t\t\tplayerFreeRefreshesGainedThisCombat:\r\n\t\t\t\t\tplayerEntity?.globalInfo?.FreeRefreshesGainedThisCombat ?? 0,\r\n\t\t\t\topponentFreeRefreshesGainedThisCombat:\r\n\t\t\t\t\topponentEntity?.globalInfo?.FreeRefreshesGainedThisCombat ?? 0,\r\n\t\t\t\tplayerFodderRefreshes: playerEntity?.globalInfo?.fodderRefreshes ?? 0,\r\n\t\t\t\topponentFodderRefreshes: opponentEntity?.globalInfo?.fodderRefreshes ?? 0,\r\n\t\t\t\tplayerGlobalInfo: { ...(playerEntity?.globalInfo ?? {}) },\r\n\t\t\t\topponentGlobalInfo: { ...(opponentEntity?.globalInfo ?? {}) },\r\n\t\t\t\tplayerHand: snapshotHand(playerEntity?.hand),\r\n\t\t\t\topponentHand: snapshotHand(opponentEntity?.hand),\r\n\t\t\t\tplayerSecrets: snapshotSecrets(playerEntity?.secrets),\r\n\t\t\t\topponentSecrets: snapshotSecrets(opponentEntity?.secrets),\r\n\t\t\t\tplayerTrinkets: snapshotTrinkets(playerEntity?.trinkets),\r\n\t\t\t\topponentTrinkets: snapshotTrinkets(opponentEntity?.trinkets),\r\n\t\t\t\tplayerHeroPowers: snapshotHeroPowers(playerEntity?.heroPowers),\r\n\t\t\t\topponentHeroPowers: snapshotHeroPowers(opponentEntity?.heroPowers),\r\n\t\t\t};\r\n\t\t\tif (t0) {\r\n\t\t\t\tcombatProfileAdd('writebackMs', performance.now() - t0);\r\n\t\t\t}\r\n\t\t\treturn packed;\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 withQuestWriteback({\r\n\t\t\t\tresult: 'tied',\r\n\t\t\t\tdamageDealt: 0,\r\n\t\t\t\tplayerBoard: snapshotBoard(playerBoard),\r\n\t\t\t\topponentBoard: snapshotBoard(opponentBoard),\r\n\t\t\t});\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 withQuestWriteback({\r\n\t\t\t\tresult: 'lost',\r\n\t\t\t\tdamageDealt: damage,\r\n\t\t\t\tplayerBoard: snapshotBoard(playerBoard),\r\n\t\t\t\topponentBoard: snapshotBoard(opponentBoard),\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 withQuestWriteback({\r\n\t\t\tresult: 'won',\r\n\t\t\tdamageDealt: damage,\r\n\t\t\tplayerBoard: snapshotBoard(playerBoard),\r\n\t\t\topponentBoard: snapshotBoard(opponentBoard),\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 profile = combatProfileEnabled();\r\n\t\tconst socT0 = profile ? performance.now() : 0;\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\tconst socMs = profile ? performance.now() - socT0 : 0;\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\tconst atkT0 = profile ? performance.now() : 0;\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\tif (profile) {\r\n\t\t\tcombatProfileAdd('socMs', socMs);\r\n\t\t\tcombatProfileAdd('atkMs', performance.now() - atkT0);\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\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\t!!this.gameState.isDuos,\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":";;;AAAA,iEAAqE;AAGrE,gDAA4C;AAE5C,oCAAgE;AAChE,qCAA0C;AAC1C,mCAA+C;AAC/C,qDAA0E;AAC1E,6CAAoD;AAEpD,uDAA0D;AAC1D,uCAA+D;AAC/D,uEAAwE;AACxE,2DAA6D;AAG7D,MAAa,SAAS;IAOrB,YAA6B,SAAwB;QAAxB,cAAS,GAAT,SAAS,CAAe;QAL7C,yBAAoB,GAAG,CAAC,CAAC,CAAC;QAE1B,+BAA0B,GAAG,KAAK,CAAC;IAGa,CAAC;IAIlD,oBAAoB,CAAC,WAAwB,EAAE,aAA0B;;QAC/E,IAAI,WAAW,GAAkB,WAAW,CAAC,KAAK,CAAC;QACnD,IAAI,YAAY,GAAoB,WAAW,CAAC,MAAM,CAAC;QACvD,IAAI,aAAa,GAAkB,aAAa,CAAC,KAAK,CAAC;QACvD,IAAI,cAAc,GAAoB,aAAa,CAAC,MAAM,CAAC;QAE3D,YAAY,CAAC,UAAU,GAAG,MAAA,YAAY,CAAC,UAAU,mCAAI,EAAE,CAAC;QACxD,cAAc,CAAC,UAAU,GAAG,MAAA,cAAc,CAAC,UAAU,mCAAI,EAAE,CAAC;QAC5D,YAAY,CAAC,UAAU,CAAC,4BAA4B,GAAG,CAAC,CAAC;QACzD,cAAc,CAAC,UAAU,CAAC,4BAA4B,GAAG,CAAC,CAAC;QAC3D,YAAY,CAAC,UAAU,CAAC,6BAA6B,GAAG,CAAC,CAAC;QAC1D,cAAc,CAAC,UAAU,CAAC,6BAA6B,GAAG,CAAC,CAAC;QAE5D,IAAI,WAAW,GAAG,CAAC,QAAQ,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,aAAa,EAAE,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE;YACzF,KAAK,MAAM,MAAM,IAAI,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,EAAE;gBACjC,IAAI,MAAM,CAAC,QAAQ,GAAG,WAAW,EAAE;oBAClC,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC;iBAC9B;gBACD,KAAK,MAAM,WAAW,IAAI,MAAA,MAAM,CAAC,YAAY,mCAAI,EAAE,EAAE;oBACpD,IAAI,WAAW,CAAC,cAAc,GAAG,WAAW,EAAE;wBAC7C,WAAW,GAAG,WAAW,CAAC,cAAc,CAAC;qBACzC;iBACD;aACD;SACD;QACD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,eAAe,GAAG,WAAW,GAAG,CAAC,CAAC;QAE7D,OACC,CAAC,YAAY,CAAC,iBAAiB;YAC/B,CAAC,cAAc,CAAC,iBAAiB;YACjC,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,IAAG,CAAC,IAAI,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,IAAG,CAAC,CAAC,EACrD;YAGD,IAAI,wBAAU,aAAV,wBAAU,uBAAV,wBAAU,CAAE,MAAM,EAAE;gBACvB,IAAI,CAAC,2BAA2B,CAAC,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC;aAC3F;YACD,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC;YACxF,IAAI,IAAI,CAAC,0BAA0B,EAAE;gBACpC,MAAM;aACN;YAID,MAAM,oBAAoB,GACzB,WAAW,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBAC5B,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;gBACxD,aAAa,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBAC9B,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;YAC5D,IAAI,oBAAoB,EAAE;gBACzB,WAAW,CAAC,KAAK,GAAG,EAAE,CAAC;gBACvB,aAAa,CAAC,KAAK,GAAG,EAAE,CAAC;aACzB;YAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;YAC1F,MAAM,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;YAChG,IAAI,gBAAgB,EAAE;gBACrB,WAAW,GAAG,MAAA,WAAW,CAAC,QAAQ,0CAAE,KAAK,CAAC;gBAC1C,WAAW,CAAC,KAAK,GAAG,EAAE,CAAC;gBACvB,YAAY,GAAG,MAAA,WAAW,CAAC,QAAQ,0CAAE,MAAM,CAAC;aAC5C;iBAAM;gBACN,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC;gBAChC,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC;aAClC;YACD,IAAI,kBAAkB,EAAE;gBACvB,aAAa,GAAG,MAAA,aAAa,CAAC,QAAQ,0CAAE,KAAK,CAAC;gBAC9C,aAAa,CAAC,KAAK,GAAG,EAAE,CAAC;gBACzB,cAAc,GAAG,MAAA,aAAa,CAAC,QAAQ,0CAAE,MAAM,CAAC;aAChD;iBAAM;gBACN,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC;gBACpC,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC;aACtC;YAKD,IAAI,gBAAgB,IAAI,YAAY,EAAE;gBAErC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAC3E,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CACrE,CAAC;gBACF,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,GAAG;oBAC1C,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK;oBAC5C,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM;iBAC9C,CAAC;gBACF,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC;gBACtD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC;aAIpD;YACD,IAAI,kBAAkB,IAAI,cAAc,EAAE;gBAEzC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAC3E,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CACvE,CAAC;gBACF,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,GAAG;oBAC5C,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK;oBAC9C,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM;iBAChD,CAAC;gBACF,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,GAAG,cAAc,CAAC;gBAC1D,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,GAAG,aAAa,CAAC;aACxD;YAED,IAAI,CAAC,YAAY,IAAI,CAAC,cAAc,EAAE;gBACrC,MAAM;aACN;SACD;QAED,MAAM,aAAa,GAAG,CAAC,KAAuC,EAAiB,EAAE,CAChF,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;;YAAC,OAAA,CAAC;gBACzB,GAAG,CAAC;gBACJ,YAAY,EAAE,CAAC,GAAG,CAAC,MAAA,CAAC,CAAC,YAAY,mCAAI,EAAE,CAAC,CAAC;gBACzC,kBAAkB,EAAE,CAAC,GAAG,CAAC,MAAA,CAAC,CAAC,kBAAkB,mCAAI,EAAE,CAAC,CAAC;gBACrD,eAAe,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe;aAC/E,CAAC,CAAA;SAAA,CAAC,CAAC;QAEL,MAAM,cAAc,GAAG,CAAC,IAAwC,EAAE,EAAE;;YAAC,OAAA,CAAC;gBACrE,aAAa,EAAE,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,mCAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;gBACjE,YAAY,EAAE,CAAC,GAAG,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,YAAY,mCAAI,EAAE,CAAC,CAAC;gBAC7C,mBAAmB,EAAE,CAAC,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,mBAAmB,mCAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;aAC7E,CAAC,CAAA;SAAA,CAAC;QAEH,MAAM,kBAAkB,GAAG,CAC1B,IAwBC,EACwB,EAAE;;YAC3B,MAAM,EAAE,GAAG,IAAA,qCAAoB,GAAE,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;YAC7C,MAAM,SAAS,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;YACjD,MAAM,YAAY,GAAG,CAAC,IAA8B,EAAE,EAAE,CACvD,CAAC,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;;gBAAC,OAAA,CAAC;oBACxB,GAAG,CAAC;oBACJ,YAAY,EAAE,CAAC,GAAG,CAAC,MAAA,CAAC,CAAC,YAAY,mCAAI,EAAE,CAAC,CAAC;oBACzC,eAAe,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe;iBAC/E,CAAC,CAAA;aAAA,CAAC,CAAC;YACL,MAAM,eAAe,GAAG,CAAC,OAAoC,EAAE,EAAE,CAChE,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACpE,MAAM,gBAAgB,GAAG,CAAC,QAAsC,EAAE,EAAE,CACnE,CAAC,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACzC,MAAM,kBAAkB,GAAG,CAAC,GAAmC,EAAE,EAAE,CAAC,CAAC,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;YACzG,MAAM,MAAM,GAA2B;gBACtC,GAAG,IAAI;gBACP,mBAAmB,EAAE,OAAO,CAAC,aAAa;gBAC1C,kBAAkB,EAAE,OAAO,CAAC,YAAY;gBACxC,yBAAyB,EAAE,OAAO,CAAC,mBAAmB;gBACtD,qBAAqB,EAAE,SAAS,CAAC,aAAa;gBAC9C,oBAAoB,EAAE,SAAS,CAAC,YAAY;gBAC5C,2BAA2B,EAAE,SAAS,CAAC,mBAAmB;gBAC1D,4BAA4B,EAAE,MAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,UAAU,0CAAE,4BAA4B,mCAAI,CAAC;gBACzF,8BAA8B,EAAE,MAAA,MAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU,0CAAE,4BAA4B,mCAAI,CAAC;gBAC7F,mCAAmC,EAAE,MAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,UAAU,0CAAE,6BAA6B,mCAAI,CAAC;gBACjG,qCAAqC,EAAE,MAAA,MAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU,0CAAE,6BAA6B,mCAAI,CAAC;gBACrG,qBAAqB,EAAE,MAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,UAAU,0CAAE,eAAe,mCAAI,CAAC;gBACrE,uBAAuB,EAAE,MAAA,MAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU,0CAAE,eAAe,mCAAI,CAAC;gBACzE,gBAAgB,EAAE,EAAE,GAAG,CAAC,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,UAAU,mCAAI,EAAE,CAAC,EAAE;gBACzD,kBAAkB,EAAE,EAAE,GAAG,CAAC,MAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU,mCAAI,EAAE,CAAC,EAAE;gBAC7D,UAAU,EAAE,YAAY,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,IAAI,CAAC;gBAC5C,YAAY,EAAE,YAAY,CAAC,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,IAAI,CAAC;gBAChD,aAAa,EAAE,eAAe,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,OAAO,CAAC;gBACrD,eAAe,EAAE,eAAe,CAAC,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,OAAO,CAAC;gBACzD,cAAc,EAAE,gBAAgB,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,QAAQ,CAAC;gBACxD,gBAAgB,EAAE,gBAAgB,CAAC,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,QAAQ,CAAC;gBAC5D,gBAAgB,EAAE,kBAAkB,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,UAAU,CAAC;gBAC9D,kBAAkB,EAAE,kBAAkB,CAAC,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU,CAAC;aAClE,CAAC;YACF,IAAI,EAAE,EAAE;gBACP,IAAA,iCAAgB,EAAC,aAAa,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;aACxD;YACD,OAAO,MAAM,CAAC;QACf,CAAC,CAAC;QAEF,IACC,CAAC,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,CAAA,IAAI,CAAC,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,CAAA,CAAC;YAEhD,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,IAAG,CAAC,IAAI,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,IAAG,CAAC,CAAC,EACrD;YACD,OAAO,kBAAkB,CAAC;gBACzB,MAAM,EAAE,MAAM;gBACd,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,aAAa,CAAC,WAAW,CAAC;gBACvC,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC;aAC3C,CAAC,CAAC;SACH;QACD,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,CAAA,IAAI,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,KAAI,CAAC,EAAE;YACtD,MAAM,WAAW,GAAG,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,aAAa,CAAC,MAAM,CAAC;YAC3D,MAAM,UAAU,GAAG,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,WAAW,CAAC,MAAM,CAAC;YACtD,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAC1B,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,0CAAE,QAAQ,0CAAE,KAAK,CAAC;gBAC5F,CAAC,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,UAAU,mCAAI,CAAC,CAAC,CAC/B,CAAC;YAEF,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,MAAM,GAAG,CAAC,IAAI,IAAA,4CAAkC,EAAC,UAAU,CAAC,EAAE;gBACjG,MAAM,GAAG,CAAC,CAAC;aACX;YACD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,sBAAsB,CAAC,WAAW,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;YACpF,OAAO,kBAAkB,CAAC;gBACzB,MAAM,EAAE,MAAM;gBACd,WAAW,EAAE,MAAM;gBACnB,WAAW,EAAE,aAAa,CAAC,WAAW,CAAC;gBACvC,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC;aAC3C,CAAC,CAAC;SACH;QAED,MAAM,WAAW,GAAG,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,WAAW,CAAC,MAAM,CAAC;QACvD,MAAM,UAAU,GAAG,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,aAAa,CAAC,MAAM,CAAC;QAC1D,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAC1B,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,MAAA,MAAA,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,0CAAE,QAAQ,0CAAE,KAAK,CAAC;YACxF,CAAC,MAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,UAAU,mCAAI,CAAC,CAAC,CAC/B,CAAC;QACF,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,MAAM,GAAG,CAAC,IAAI,IAAA,4CAAkC,EAAC,UAAU,CAAC,EAAE;YACjG,MAAM,GAAG,CAAC,CAAC;SACX;QACD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,oBAAoB,CAAC,WAAW,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;QAClF,OAAO,kBAAkB,CAAC;YACzB,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,MAAM;YACnB,WAAW,EAAE,aAAa,CAAC,WAAW,CAAC;YACvC,aAAa,EAAE,aAAa,CAAC,aAAa,CAAC;SAC3C,CAAC,CAAC;IACJ,CAAC;IAEO,2BAA2B,CAClC,WAA0B,EAC1B,YAA6B,EAC7B,aAA4B,EAC5B,cAA+B;;QAE/B,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,CAAC,WAAW,EAAE,aAAa,EAAE,YAAY,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE;YACzF,KAAK,MAAM,MAAM,IAAI,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,EAAE;gBACjC,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAA,MAAA,MAAM,CAAC,YAAY,0CAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,mCAAI,EAAE,CAAC,CAAC,CAAC;gBAC/F,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;oBACxB,OAAO,CAAC,GAAG,CACV,8BAA8B,EAC9B,MAAM,CAAC,MAAM,EACb,IAAA,2BAAmB,EAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CACpD,CAAC;iBACF;gBACD,YAAY,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;aAC7B;SACD;QACD,IAAI,YAAY,CAAC,MAAM,GAAG,KAAK,EAAE;YAChC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,EAAE,IAAI,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;SAC9D;IACF,CAAC;IAEO,wBAAwB,CAC/B,WAA0B,EAC1B,YAA6B,EAC7B,aAA4B,EAC5B,cAA+B;;QAE/B,IAAI,wBAAU,aAAV,wBAAU,uBAAV,wBAAU,CAAE,MAAM,EAAE;YACvB,wBAAU,CAAC,aAAa,EAAE,CAAC;SAC3B;QAGD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,qBAAqB,CAAC,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;QAMzG,MAAM,0BAA0B,GAAG,WAAW,CAAC,MAAM,CAAC;QACtD,MAAM,4BAA4B,GAAG,aAAa,CAAC,MAAM,CAAC;QAC1D,IAAI,CAAC,eAAe;YACnB,0BAA0B,GAAG,4BAA4B;gBACxD,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,4BAA4B,GAAG,0BAA0B;oBAC3D,CAAC,CAAC,CAAC;oBACH,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAA,qCAAoB,GAAE,CAAC;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,2BAA2B,GAAG,IAAA,qCAAmB,EACtD,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,SAAS,CACd,CAAC;QACF,IAAI,CAAC,eAAe,GAAG,2BAA2B,CAAC;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,wBAAU,aAAV,wBAAU,uBAAV,wBAAU,CAAE,MAAM,EAAE;YACvB,IAAI,CAAC,eAAe,GAAG,MAAA,wBAAU,CAAC,qBAAqB,mCAAI,IAAI,CAAC,eAAe,CAAC;SAChF;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,OACC,WAAW,CAAC,MAAM,GAAG,CAAC;YACtB,aAAa,CAAC,MAAM,GAAG,CAAC;YACxB,YAAY,CAAC,MAAM,GAAG,CAAC;YACvB,cAAc,CAAC,MAAM,GAAG,CAAC,EACxB;YACD,IAAA,4BAAoB,EAAC,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAY/F,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;gBAC3D,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;aAC9B;iBAAM,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;gBACpE,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;aAC9B;iBAAM;gBACN,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;aAC/B;YACD,IACC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;gBACpD,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EACrD;gBACD,MAAM;aACN;YAGD,IAAI,IAAI,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC,CAAC,EAAE;gBACxG,IAAA,uBAAc,EAAC,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;aACzF;iBAAM;gBACN,IAAA,uBAAc,EAAC,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;aACzF;YAED,IAAA,uCAAqB,EAAC,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAEhG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;gBAC3D,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;aAC9B;iBAAM,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;gBACpE,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;aAC9B;iBAAM;gBACN,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;gBAC/B,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;aACtD;YACD,OAAO,EAAE,CAAC;YACV,IAAI,OAAO,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,0BAA0B,EAAE;gBACtD,OAAO,CAAC,IAAI,CACX,kDAAkD,EAClD,OAAO,EACP,IAAI,EACJ,IAAA,uBAAe,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EACrD,IAAI,EACJ,IAAA,uBAAe,EAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CACvD,CAAC;gBACF,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;gBACvC,MAAM;aAEN;YACD,IAAA,0CAAsB,EAAC,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;SACjG;QACD,IAAI,OAAO,EAAE;YACZ,IAAA,iCAAgB,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACjC,IAAA,iCAAgB,EAAC,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;SACrD;IACF,CAAC;IAEO,SAAS,CAAC,MAAc;QAC/B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE;YACnC,OAAO,MAAM,CAAC;SACd;QACD,OAAO,IAAA,iCAAoB,EAC1B,MAAM,EACN,IAAI,CAAC,SAAS,CAAC,WAAW,EAC1B,IAAI,CAAC,SAAS,CAAC,oBAAoB,EACnC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CACvB,CAAC;IACH,CAAC;IAEO,qBAAqB,CAAC,WAAmC,EAAE,aAA6B;;QAC/F,MAAM,qBAAqB,GAAG,WAAW;aACvC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACf,IAAA,sCAAqB,EAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAC9F;aACA,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7B,MAAM,+BAA+B,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC;QAC/D,MAAM,uBAAuB,GAC5B,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CACV,KAAK,CAAC,CAAC,EAAE,+BAA+B,EACzC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACf,IAAA,sCAAqB,EAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAE9F,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,mCAAI,CAAC,CAAC;QACnC,OAAO,qBAAqB,GAAG,uBAAuB,CAAC;IACxD,CAAC;CACD;AAvaD,8BAuaC","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 { combatProfileAdd, combatProfileEnabled } from './combat-profile';\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\tplayerEntity.globalInfo = playerEntity.globalInfo ?? {};\r\n\t\topponentEntity.globalInfo = opponentEntity.globalInfo ?? {};\r\n\t\tplayerEntity.globalInfo.RallyMinionAttacksThisCombat = 0;\r\n\t\topponentEntity.globalInfo.RallyMinionAttacksThisCombat = 0;\r\n\t\tplayerEntity.globalInfo.FreeRefreshesGainedThisCombat = 0;\r\n\t\topponentEntity.globalInfo.FreeRefreshesGainedThisCombat = 0;\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\tconst snapshotBoard = (board: BoardEntity[] | null | undefined): BoardEntity[] =>\r\n\t\t\t(board ?? []).map((e) => ({\r\n\t\t\t\t...e,\r\n\t\t\t\tenchantments: [...(e.enchantments ?? [])],\r\n\t\t\t\tpendingAttackBuffs: [...(e.pendingAttackBuffs ?? [])],\r\n\t\t\t\tadditionalCards: e.additionalCards ? [...e.additionalCards] : e.additionalCards,\r\n\t\t\t}));\r\n\r\n\t\tconst snapshotQuests = (hero: BgsPlayerEntity | null | undefined) => ({\r\n\t\t\tquestEntities: (hero?.questEntities ?? []).map((q) => ({ ...q })),\r\n\t\t\tquestRewards: [...(hero?.questRewards ?? [])],\r\n\t\t\tquestRewardEntities: (hero?.questRewardEntities ?? []).map((r) => ({ ...r })),\r\n\t\t});\r\n\r\n\t\tconst withQuestWriteback = (\r\n\t\t\tbase: Omit<\r\n\t\t\t\tSingleSimulationResult,\r\n\t\t\t\t| 'playerQuestEntities'\r\n\t\t\t\t| 'playerQuestRewards'\r\n\t\t\t\t| 'playerQuestRewardEntities'\r\n\t\t\t\t| 'opponentQuestEntities'\r\n\t\t\t\t| 'opponentQuestRewards'\r\n\t\t\t\t| 'opponentQuestRewardEntities'\r\n\t\t\t\t| 'playerRallyAttacksThisCombat'\r\n\t\t\t\t| 'opponentRallyAttacksThisCombat'\r\n\t\t\t\t| 'playerFreeRefreshesGainedThisCombat'\r\n\t\t\t\t| 'opponentFreeRefreshesGainedThisCombat'\r\n\t\t\t\t| 'playerFodderRefreshes'\r\n\t\t\t\t| 'opponentFodderRefreshes'\r\n\t\t\t\t| 'playerGlobalInfo'\r\n\t\t\t\t| 'opponentGlobalInfo'\r\n\t\t\t\t| 'playerHand'\r\n\t\t\t\t| 'opponentHand'\r\n\t\t\t\t| 'playerSecrets'\r\n\t\t\t\t| 'opponentSecrets'\r\n\t\t\t\t| 'playerTrinkets'\r\n\t\t\t\t| 'opponentTrinkets'\r\n\t\t\t\t| 'playerHeroPowers'\r\n\t\t\t\t| 'opponentHeroPowers'\r\n\t\t\t>,\r\n\t\t): SingleSimulationResult => {\r\n\t\t\tconst t0 = combatProfileEnabled() ? performance.now() : 0;\r\n\t\t\tconst playerQ = snapshotQuests(playerEntity);\r\n\t\t\tconst opponentQ = snapshotQuests(opponentEntity);\r\n\t\t\tconst snapshotHand = (hand: typeof playerEntity.hand) =>\r\n\t\t\t\t(hand ?? []).map((e) => ({\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\tenchantments: [...(e.enchantments ?? [])],\r\n\t\t\t\t\tadditionalCards: e.additionalCards ? [...e.additionalCards] : e.additionalCards,\r\n\t\t\t\t}));\r\n\t\t\tconst snapshotSecrets = (secrets: typeof playerEntity.secrets) =>\r\n\t\t\t\t(secrets ?? []).filter((s) => !s.triggered).map((s) => ({ ...s }));\r\n\t\t\tconst snapshotTrinkets = (trinkets: typeof playerEntity.trinkets) =>\r\n\t\t\t\t(trinkets ?? []).map((t) => ({ ...t }));\r\n\t\t\tconst snapshotHeroPowers = (hps: typeof playerEntity.heroPowers) => (hps ?? []).map((hp) => ({ ...hp }));\r\n\t\t\tconst packed: SingleSimulationResult = {\r\n\t\t\t\t...base,\r\n\t\t\t\tplayerQuestEntities: playerQ.questEntities,\r\n\t\t\t\tplayerQuestRewards: playerQ.questRewards,\r\n\t\t\t\tplayerQuestRewardEntities: playerQ.questRewardEntities,\r\n\t\t\t\topponentQuestEntities: opponentQ.questEntities,\r\n\t\t\t\topponentQuestRewards: opponentQ.questRewards,\r\n\t\t\t\topponentQuestRewardEntities: opponentQ.questRewardEntities,\r\n\t\t\t\tplayerRallyAttacksThisCombat: playerEntity?.globalInfo?.RallyMinionAttacksThisCombat ?? 0,\r\n\t\t\t\topponentRallyAttacksThisCombat: opponentEntity?.globalInfo?.RallyMinionAttacksThisCombat ?? 0,\r\n\t\t\t\tplayerFreeRefreshesGainedThisCombat: playerEntity?.globalInfo?.FreeRefreshesGainedThisCombat ?? 0,\r\n\t\t\t\topponentFreeRefreshesGainedThisCombat: opponentEntity?.globalInfo?.FreeRefreshesGainedThisCombat ?? 0,\r\n\t\t\t\tplayerFodderRefreshes: playerEntity?.globalInfo?.fodderRefreshes ?? 0,\r\n\t\t\t\topponentFodderRefreshes: opponentEntity?.globalInfo?.fodderRefreshes ?? 0,\r\n\t\t\t\tplayerGlobalInfo: { ...(playerEntity?.globalInfo ?? {}) },\r\n\t\t\t\topponentGlobalInfo: { ...(opponentEntity?.globalInfo ?? {}) },\r\n\t\t\t\tplayerHand: snapshotHand(playerEntity?.hand),\r\n\t\t\t\topponentHand: snapshotHand(opponentEntity?.hand),\r\n\t\t\t\tplayerSecrets: snapshotSecrets(playerEntity?.secrets),\r\n\t\t\t\topponentSecrets: snapshotSecrets(opponentEntity?.secrets),\r\n\t\t\t\tplayerTrinkets: snapshotTrinkets(playerEntity?.trinkets),\r\n\t\t\t\topponentTrinkets: snapshotTrinkets(opponentEntity?.trinkets),\r\n\t\t\t\tplayerHeroPowers: snapshotHeroPowers(playerEntity?.heroPowers),\r\n\t\t\t\topponentHeroPowers: snapshotHeroPowers(opponentEntity?.heroPowers),\r\n\t\t\t};\r\n\t\t\tif (t0) {\r\n\t\t\t\tcombatProfileAdd('writebackMs', performance.now() - t0);\r\n\t\t\t}\r\n\t\t\treturn packed;\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 withQuestWriteback({\r\n\t\t\t\tresult: 'tied',\r\n\t\t\t\tdamageDealt: 0,\r\n\t\t\t\tplayerBoard: snapshotBoard(playerBoard),\r\n\t\t\t\topponentBoard: snapshotBoard(opponentBoard),\r\n\t\t\t});\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 (this.gameState.applyIceBlock && damage > 0 && tryPreventCombatDamageWithIceBlock(losingHero)) {\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 withQuestWriteback({\r\n\t\t\t\tresult: 'lost',\r\n\t\t\t\tdamageDealt: damage,\r\n\t\t\t\tplayerBoard: snapshotBoard(playerBoard),\r\n\t\t\t\topponentBoard: snapshotBoard(opponentBoard),\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 (this.gameState.applyIceBlock && damage > 0 && tryPreventCombatDamageWithIceBlock(losingHero)) {\r\n\t\t\tdamage = 0;\r\n\t\t}\r\n\t\tthis.gameState.spectator.registerPlayerAttack(playerBoard, opponentBoard, damage);\r\n\t\treturn withQuestWriteback({\r\n\t\t\tresult: 'won',\r\n\t\t\tdamageDealt: damage,\r\n\t\t\tplayerBoard: snapshotBoard(playerBoard),\r\n\t\t\topponentBoard: snapshotBoard(opponentBoard),\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 profile = combatProfileEnabled();\r\n\t\tconst socT0 = profile ? performance.now() : 0;\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\tconst socMs = profile ? performance.now() - socT0 : 0;\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\tconst atkT0 = profile ? performance.now() : 0;\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\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\thandleSummonsWhenSpace(playerBoard, playerEntity, opponentBoard, opponentEntity, this.gameState);\r\n\t\t}\r\n\t\tif (profile) {\r\n\t\t\tcombatProfileAdd('socMs', socMs);\r\n\t\t\tcombatProfileAdd('atkMs', performance.now() - atkT0);\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\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\t!!this.gameState.isDuos,\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"]}
@@ -3,4 +3,4 @@ import { BoardEntity } from '../../board-entity';
3
3
  import { BoardSecret } from '../../board-secret';
4
4
  import { StartOfCombatTiming } from '../../cards/card.interface';
5
5
  import { SoCInput } from './start-of-combat-input';
6
- export declare const performStartOfCombatAction: (cardId: string, entity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret, input: SoCInput, processDeaths: boolean, timing?: StartOfCombatTiming) => boolean;
6
+ export declare const performStartOfCombatAction: (cardId: string, entity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret, input: SoCInput, processDeaths: boolean, timing?: StartOfCombatTiming, doSummonsWhenSpace?: boolean) => boolean;
@@ -61,7 +61,7 @@ const training_certificate_1 = require("../../cards/impl/trinket/training-certif
61
61
  const valorous_medaillion_1 = require("../../cards/impl/trinket/valorous-medaillion");
62
62
  const attack_1 = require("../attack");
63
63
  const summon_when_space_1 = require("../summon-when-space");
64
- const performStartOfCombatAction = (cardId, entity, input, processDeaths, timing) => {
64
+ const performStartOfCombatAction = (cardId, entity, input, processDeaths, timing, doSummonsWhenSpace = true) => {
65
65
  let hasTriggered = false;
66
66
  const promoPortraitCount = getPromoPortraitCount(input.playerEntity);
67
67
  for (let i = promoPortraitCount; i >= 0; i--) {
@@ -76,13 +76,15 @@ const performStartOfCombatAction = (cardId, entity, input, processDeaths, timing
76
76
  if (!!hasTriggered) {
77
77
  if (processDeaths) {
78
78
  (0, attack_1.processMinionDeath)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState, true);
79
- const shouldRecomputeCurrentAttacker = (0, summon_when_space_1.handleSummonsWhenSpace)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState);
80
- if (typeof hasTriggered === 'boolean') {
81
- hasTriggered = hasTriggered || shouldRecomputeCurrentAttacker;
82
- }
83
- else {
84
- hasTriggered.shouldRecomputeCurrentAttacker =
85
- hasTriggered.shouldRecomputeCurrentAttacker || shouldRecomputeCurrentAttacker;
79
+ if (doSummonsWhenSpace) {
80
+ const shouldRecomputeCurrentAttacker = (0, summon_when_space_1.handleSummonsWhenSpace)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState);
81
+ if (typeof hasTriggered === 'boolean') {
82
+ hasTriggered = hasTriggered || shouldRecomputeCurrentAttacker;
83
+ }
84
+ else {
85
+ hasTriggered.shouldRecomputeCurrentAttacker =
86
+ hasTriggered.shouldRecomputeCurrentAttacker || shouldRecomputeCurrentAttacker;
87
+ }
86
88
  }
87
89
  }
88
90
  if (typeof hasTriggered !== 'boolean' && hasTriggered.shouldRecomputeCurrentAttacker) {