@firestone-hs/simulate-bgs-battle 1.1.758 → 1.1.761
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.
- package/dist/board-entity.d.ts +1 -0
- package/dist/board-entity.js.map +1 -1
- package/dist/cards/cards-data.d.ts +1 -0
- package/dist/cards/cards-data.js +5 -0
- package/dist/cards/cards-data.js.map +1 -1
- package/dist/cards/impl/bg-spell/brood-of-nozdormu.js +1 -1
- package/dist/cards/impl/bg-spell/brood-of-nozdormu.js.map +1 -1
- package/dist/cards/impl/enchantments/deaths-embrace.js +1 -3
- package/dist/cards/impl/enchantments/deaths-embrace.js.map +1 -1
- package/dist/cards/impl/enchantments/doppelganger.js +1 -1
- package/dist/cards/impl/enchantments/doppelganger.js.map +1 -1
- package/dist/cards/impl/enchantments/spell-siphon.d.ts +2 -2
- package/dist/cards/impl/enchantments/spell-siphon.js +46 -5
- package/dist/cards/impl/enchantments/spell-siphon.js.map +1 -1
- package/dist/cards/impl/minion/bramble-tunneler.js +1 -1
- package/dist/cards/impl/minion/bramble-tunneler.js.map +1 -1
- package/dist/cards/impl/minion/lurking-leviathan.js +2 -1
- package/dist/cards/impl/minion/lurking-leviathan.js.map +1 -1
- package/dist/cards/impl/minion/relentless-deflector.js +3 -0
- package/dist/cards/impl/minion/relentless-deflector.js.map +1 -1
- package/dist/cards/impl/minion/sinrunner-blanchy.js +1 -0
- package/dist/cards/impl/minion/sinrunner-blanchy.js.map +1 -1
- package/dist/cards/impl/minion/tasty-lobster.js +3 -1
- package/dist/cards/impl/minion/tasty-lobster.js.map +1 -1
- package/dist/cards/impl/minion/underrot-spawn.js +1 -1
- package/dist/cards/impl/minion/underrot-spawn.js.map +1 -1
- package/dist/cards/impl/minion/wildfire-elemental.js +2 -1
- package/dist/cards/impl/minion/wildfire-elemental.js.map +1 -1
- package/dist/cards/impl/trinket/hammer-of-twilight.js +10 -3
- package/dist/cards/impl/trinket/hammer-of-twilight.js.map +1 -1
- package/dist/input-sanitation.js +1 -0
- package/dist/input-sanitation.js.map +1 -1
- package/dist/simulation/add-minion-to-board.js +12 -1
- package/dist/simulation/add-minion-to-board.js.map +1 -1
- package/dist/simulation/death-effects.js +11 -2
- package/dist/simulation/death-effects.js.map +1 -1
- package/dist/simulation/deathrattle-orchestration.js +2 -1
- package/dist/simulation/deathrattle-orchestration.js.map +1 -1
- package/dist/simulation/deity.d.ts +8 -0
- package/dist/simulation/deity.js +65 -3
- package/dist/simulation/deity.js.map +1 -1
- package/dist/simulation/minion-death.js +5 -1
- package/dist/simulation/minion-death.js.map +1 -1
- package/dist/simulation/simulator.js +5 -11
- package/dist/simulation/simulator.js.map +1 -1
- package/dist/simulation/spectator/game-action.d.ts +1 -0
- package/dist/simulation/spectator/game-action.js +24 -3
- package/dist/simulation/spectator/game-action.js.map +1 -1
- package/dist/simulation/spectator/spectator.js +2 -0
- package/dist/simulation/spectator/spectator.js.map +1 -1
- package/dist/simulation/start-of-combat/soc-action-processor.d.ts +1 -1
- package/dist/simulation/start-of-combat/soc-action-processor.js +10 -8
- package/dist/simulation/start-of-combat/soc-action-processor.js.map +1 -1
- package/dist/simulation/start-of-combat/soc-minion.js +3 -12
- package/dist/simulation/start-of-combat/soc-minion.js.map +1 -1
- package/dist/simulation/start-of-combat/start-of-combat.js +3 -0
- package/dist/simulation/start-of-combat/start-of-combat.js.map +1 -1
- package/dist/simulation/summon-when-space.js +1 -0
- package/dist/simulation/summon-when-space.js.map +1 -1
- 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"]}
|
|
@@ -11,8 +11,16 @@ export declare const getDeityBaseStats: (hero: BgsPlayerEntity, entity?: BoardEn
|
|
|
11
11
|
attack: number;
|
|
12
12
|
health: number;
|
|
13
13
|
};
|
|
14
|
+
export declare const getDeityAuraSnapshot: (entity: BoardEntity, hero: BgsPlayerEntity) => {
|
|
15
|
+
attack: number;
|
|
16
|
+
health: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const stampOnBoardDeityAuras: (board: BoardEntity[], hero: BgsPlayerEntity, allCards: AllCardsService) => void;
|
|
14
19
|
export declare const applyDeityBaseStats: (entity: BoardEntity, hero: BgsPlayerEntity) => void;
|
|
20
|
+
export declare const consumeDeityBaseStatsAssignment: (entity: BoardEntity) => boolean;
|
|
15
21
|
export declare const buffYourDeity: (hero: BgsPlayerEntity, board: BoardEntity[], source: BoardEntity | BoardSecret | BgsPlayerEntity, attack: number, health: number, gameState: FullGameState) => void;
|
|
16
22
|
export declare const incrementDeitySecretStats: (hero: BgsPlayerEntity, attack: number, health: number) => void;
|
|
17
23
|
export declare const buffTeamDeities: (hero: BgsPlayerEntity, board: BoardEntity[], source: BoardEntity, attack: number, health: number, gameState: FullGameState) => void;
|
|
18
24
|
export declare const onFriendlyAberrationDied: (deadEntity: BoardEntity, _deadEntityIndexFromRight: number, board: BoardEntity[], hero: BgsPlayerEntity, otherBoard: BoardEntity[], otherHero: BgsPlayerEntity, gameState: FullGameState) => BoardEntity[];
|
|
25
|
+
export declare const markDeitySecretTriggered: (hero: BgsPlayerEntity) => void;
|
|
26
|
+
export declare const retryDeityAwakenOnNextAberrationDeath: (hero: BgsPlayerEntity) => void;
|
package/dist/simulation/deity.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.onFriendlyAberrationDied = exports.buffTeamDeities = exports.incrementDeitySecretStats = exports.buffYourDeity = exports.applyDeityBaseStats = exports.getDeityBaseStats = exports.getOnBoardDeity = exports.getDeitySecret = exports.isAberration = exports.isDeityCard = void 0;
|
|
3
|
+
exports.retryDeityAwakenOnNextAberrationDeath = exports.markDeitySecretTriggered = exports.onFriendlyAberrationDied = exports.buffTeamDeities = exports.incrementDeitySecretStats = exports.buffYourDeity = exports.consumeDeityBaseStatsAssignment = exports.applyDeityBaseStats = exports.stampOnBoardDeityAuras = exports.getDeityAuraSnapshot = exports.getDeityBaseStats = exports.getOnBoardDeity = exports.getDeitySecret = exports.isAberration = exports.isDeityCard = void 0;
|
|
4
4
|
const reference_data_1 = require("@firestone-hs/reference-data");
|
|
5
5
|
const card_interface_1 = require("../cards/card.interface");
|
|
6
6
|
const _card_mappings_1 = require("../cards/impl/_card-mappings");
|
|
@@ -24,6 +24,8 @@ const getOnBoardDeity = (board, allCards) => {
|
|
|
24
24
|
return board.find((e) => (0, utils_1.hasEntityMechanic)(e, reference_data_1.GameTag.BACON_OLD_GOD, allCards) && e.health > 0 && !e.definitelyDead);
|
|
25
25
|
};
|
|
26
26
|
exports.getOnBoardDeity = getOnBoardDeity;
|
|
27
|
+
const awakeningSecrets = new WeakSet();
|
|
28
|
+
const deityBaseStatsAssigned = new WeakSet();
|
|
27
29
|
const readSecretAttack = (secret) => {
|
|
28
30
|
var _a, _b, _c;
|
|
29
31
|
return (_c = (_b = (_a = secret.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK]) !== null && _b !== void 0 ? _b : secret.scriptDataNum2) !== null && _c !== void 0 ? _c : 1;
|
|
@@ -48,6 +50,33 @@ const getDeityBaseStats = (hero, entity) => {
|
|
|
48
50
|
return { attack, health };
|
|
49
51
|
};
|
|
50
52
|
exports.getDeityBaseStats = getDeityBaseStats;
|
|
53
|
+
const getDeityAuraSnapshot = (entity, hero) => {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const attack = (_a = entity.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK];
|
|
56
|
+
const health = (_b = entity.tags) === null || _b === void 0 ? void 0 : _b[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH];
|
|
57
|
+
if (attack != null && health != null) {
|
|
58
|
+
return { attack, health: Math.max(1, health) };
|
|
59
|
+
}
|
|
60
|
+
return (0, exports.getDeityBaseStats)(hero, entity);
|
|
61
|
+
};
|
|
62
|
+
exports.getDeityAuraSnapshot = getDeityAuraSnapshot;
|
|
63
|
+
const stampOnBoardDeityAuras = (board, hero, allCards) => {
|
|
64
|
+
var _a, _b, _c;
|
|
65
|
+
for (const entity of board) {
|
|
66
|
+
if (!(0, exports.isDeityCard)(entity.cardId, allCards)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (((_a = entity.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK]) != null &&
|
|
70
|
+
((_b = entity.tags) === null || _b === void 0 ? void 0 : _b[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH]) != null) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const { attack, health } = (0, exports.getDeityBaseStats)(hero, entity);
|
|
74
|
+
entity.tags = (_c = entity.tags) !== null && _c !== void 0 ? _c : {};
|
|
75
|
+
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK] = attack;
|
|
76
|
+
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH] = health;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
exports.stampOnBoardDeityAuras = stampOnBoardDeityAuras;
|
|
51
80
|
const applyDeityBaseStats = (entity, hero) => {
|
|
52
81
|
var _a;
|
|
53
82
|
const { attack, health } = (0, exports.getDeityBaseStats)(hero, entity);
|
|
@@ -58,8 +87,17 @@ const applyDeityBaseStats = (entity, hero) => {
|
|
|
58
87
|
entity.tags = (_a = entity.tags) !== null && _a !== void 0 ? _a : {};
|
|
59
88
|
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK] = attack;
|
|
60
89
|
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH] = health;
|
|
90
|
+
deityBaseStatsAssigned.add(entity);
|
|
61
91
|
};
|
|
62
92
|
exports.applyDeityBaseStats = applyDeityBaseStats;
|
|
93
|
+
const consumeDeityBaseStatsAssignment = (entity) => {
|
|
94
|
+
if (!deityBaseStatsAssigned.has(entity)) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
deityBaseStatsAssigned.delete(entity);
|
|
98
|
+
return true;
|
|
99
|
+
};
|
|
100
|
+
exports.consumeDeityBaseStatsAssignment = consumeDeityBaseStatsAssignment;
|
|
63
101
|
const buffYourDeity = (hero, board, source, attack, health, gameState) => {
|
|
64
102
|
const onBoard = (0, exports.getOnBoardDeity)(board, gameState.allCards);
|
|
65
103
|
if (onBoard) {
|
|
@@ -102,7 +140,7 @@ const onFriendlyAberrationDied = (deadEntity, _deadEntityIndexFromRight, board,
|
|
|
102
140
|
return [];
|
|
103
141
|
}
|
|
104
142
|
const secret = (0, exports.getDeitySecret)(hero);
|
|
105
|
-
if (!secret || secret.triggered) {
|
|
143
|
+
if (!secret || secret.triggered || awakeningSecrets.has(secret)) {
|
|
106
144
|
return [];
|
|
107
145
|
}
|
|
108
146
|
const remaining = (secret.scriptDataNum1 || 3) - 1;
|
|
@@ -110,7 +148,11 @@ const onFriendlyAberrationDied = (deadEntity, _deadEntityIndexFromRight, board,
|
|
|
110
148
|
if (remaining > 0) {
|
|
111
149
|
return [];
|
|
112
150
|
}
|
|
113
|
-
|
|
151
|
+
if (board.length >= 7) {
|
|
152
|
+
(0, exports.retryDeityAwakenOnNextAberrationDeath)(hero);
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
awakeningSecrets.add(secret);
|
|
114
156
|
const cardId = resolveDeityCardId(secret, gameState);
|
|
115
157
|
const spawns = (0, deathrattle_spawns_1.spawnEntities)(cardId, 1, board, hero, otherBoard, otherHero, gameState, deadEntity.friendly, false, false, true);
|
|
116
158
|
for (const spawn of spawns) {
|
|
@@ -134,7 +176,27 @@ const onFriendlyAberrationDied = (deadEntity, _deadEntityIndexFromRight, board,
|
|
|
134
176
|
});
|
|
135
177
|
}
|
|
136
178
|
}
|
|
179
|
+
if (!spawns.length) {
|
|
180
|
+
secret.triggered = true;
|
|
181
|
+
}
|
|
137
182
|
return [...spawns];
|
|
138
183
|
};
|
|
139
184
|
exports.onFriendlyAberrationDied = onFriendlyAberrationDied;
|
|
185
|
+
const markDeitySecretTriggered = (hero) => {
|
|
186
|
+
const secret = (0, exports.getDeitySecret)(hero);
|
|
187
|
+
if (secret) {
|
|
188
|
+
secret.triggered = true;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
exports.markDeitySecretTriggered = markDeitySecretTriggered;
|
|
192
|
+
const retryDeityAwakenOnNextAberrationDeath = (hero) => {
|
|
193
|
+
const secret = (0, exports.getDeitySecret)(hero);
|
|
194
|
+
if (!secret) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
awakeningSecrets.delete(secret);
|
|
198
|
+
secret.triggered = false;
|
|
199
|
+
secret.scriptDataNum1 = 1;
|
|
200
|
+
};
|
|
201
|
+
exports.retryDeityAwakenOnNextAberrationDeath = retryDeityAwakenOnNextAberrationDeath;
|
|
140
202
|
//# sourceMappingURL=deity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deity.js","sourceRoot":"","sources":["../../src/simulation/deity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Deity / BG_OldGod secret.\r\n * After 3 friendly Aberrations die each combat, awaken C'Thun or Y'Shaarj with stored stats.\r\n * scriptDataNum1 = deaths remaining, tags BACON_OLD_GOD_ATTACK/HEALTH = atk/hp, scriptDataNum6 = deity dbfId.\r\n */\r\nimport { AllCardsService, GameTag, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { hasOnAwaken } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { getPlayerState, hasCorrectTribe, hasEntityMechanic, hasMechanic } from '../utils';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const isDeityCard = (cardId: string, allCards: AllCardsService): boolean => {\r\n\treturn hasMechanic(allCards.getCard(cardId), GameTag.BACON_OLD_GOD);\r\n};\r\n\r\nexport const isAberration = (entity: BoardEntity, hero: BgsPlayerEntity, gameState: FullGameState): boolean => {\r\n\treturn hasCorrectTribe(entity, hero, Race.ABERRATION, gameState.anomalies, gameState.allCards);\r\n};\r\n\r\nexport const getDeitySecret = (hero: BgsPlayerEntity): BoardSecret | undefined => {\r\n\treturn hero.secrets?.find((s) => s.cardId === CardIds.SecretDeityDnt_BG_OldGod);\r\n};\r\n\r\nexport const getOnBoardDeity = (board: BoardEntity[], allCards: AllCardsService): BoardEntity | undefined => {\r\n\treturn board.find(\r\n\t\t(e) => hasEntityMechanic(e, GameTag.BACON_OLD_GOD, allCards) && e.health > 0 && !e.definitelyDead,\r\n\t);\r\n};\r\n\r\nconst readSecretAttack = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ?? secret.scriptDataNum2 ?? 1;\r\n};\r\n\r\nconst readSecretHealth = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ?? secret.scriptDataNum3 ?? 1;\r\n};\r\n\r\nconst writeSecretStats = (secret: BoardSecret, attack: number, health: number): void => {\r\n\tsecret.scriptDataNum2 = attack;\r\n\tsecret.scriptDataNum3 = health;\r\n\tsecret.tags = secret.tags ?? {};\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n};\r\n\r\nexport const getDeityBaseStats = (hero: BgsPlayerEntity, entity?: BoardEntity): { attack: number; health: number } => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tconst attack =\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tsecret?.scriptDataNum2 ??\r\n\t\t1;\r\n\tconst health = Math.max(\r\n\t\t1,\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tsecret?.scriptDataNum3 ??\r\n\t\t\t1,\r\n\t);\r\n\treturn { attack, health };\r\n};\r\n\r\nexport const applyDeityBaseStats = (entity: BoardEntity, hero: BgsPlayerEntity): void => {\r\n\tconst { attack, health } = getDeityBaseStats(hero, entity);\r\n\tentity.attack = attack;\r\n\tentity.maxAttack = attack;\r\n\tentity.health = health;\r\n\tentity.maxHealth = health;\r\n\tentity.tags = entity.tags ?? {};\r\n\tentity.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tentity.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n};\r\n\r\nexport const buffYourDeity = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity | BoardSecret | BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst onBoard = getOnBoardDeity(board, gameState.allCards);\r\n\tif (onBoard) {\r\n\t\tmodifyStats(onBoard, source as BoardEntity, attack, health, board, hero, gameState);\r\n\t}\r\n\tincrementDeitySecretStats(hero, attack, health);\r\n};\r\n\r\nexport const incrementDeitySecretStats = (hero: BgsPlayerEntity, attack: number, health: number): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (secret) {\r\n\t\twriteSecretStats(secret, readSecretAttack(secret) + attack, readSecretHealth(secret) + health);\r\n\t}\r\n};\r\n\r\nexport const buffTeamDeities = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tbuffYourDeity(hero, board, source, attack, health, gameState);\r\n\tconst playerState = getPlayerState(gameState.gameState, hero);\r\n\tconst teammate = playerState?.teammate;\r\n\tif (teammate?.player) {\r\n\t\tbuffYourDeity(teammate.player, teammate.board ?? [], source, attack, health, gameState);\r\n\t}\r\n};\r\n\r\nconst resolveDeityCardId = (secret: BoardSecret, gameState: FullGameState): string => {\r\n\tconst dbfId = secret.scriptDataNum6 ?? secret.tags?.[GameTag.BACON_GLOBAL_OLD_GOD_DBID];\r\n\tif (dbfId) {\r\n\t\tconst fromDbf = gameState.allCards.getCardFromDbfId(dbfId);\r\n\t\tif (fromDbf?.id) {\r\n\t\t\treturn fromDbf.id;\r\n\t\t}\r\n\t}\r\n\treturn CardIds.Cthun_BGFYM_000;\r\n};\r\n\r\nexport const onFriendlyAberrationDied = (\r\n\tdeadEntity: BoardEntity,\r\n\t_deadEntityIndexFromRight: number,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): BoardEntity[] => {\r\n\tif (!isAberration(deadEntity, hero, gameState)) {\r\n\t\treturn [];\r\n\t}\r\n\t// 2026-09-22: This seems to be an HS bug, but for now the deity doesn't spawn when facing the ghost\r\n\t// Looks like this is an intermittent bug\r\n\t// if (hero.hpLeft <= 0 || hero.cardId === CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad) {\r\n\t// \treturn [];\r\n\t// }\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (!secret || secret.triggered) {\r\n\t\treturn [];\r\n\t}\r\n\tconst remaining = (secret.scriptDataNum1 || 3) - 1;\r\n\tsecret.scriptDataNum1 = remaining;\r\n\tif (remaining > 0) {\r\n\t\treturn [];\r\n\t}\r\n\tsecret.triggered = true;\r\n\tconst cardId = resolveDeityCardId(secret, gameState);\r\n\tconst spawns = spawnEntities(\r\n\t\tcardId,\r\n\t\t1,\r\n\t\tboard,\r\n\t\thero,\r\n\t\totherBoard,\r\n\t\totherHero,\r\n\t\tgameState,\r\n\t\tdeadEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t);\r\n\tfor (const spawn of spawns) {\r\n\t\tapplyDeityBaseStats(spawn, hero);\r\n\t\tif (hero.trinkets?.some((t) => t.cardId === CardIds.EvilExperiment_BG36_MagicItem_416)) {\r\n\t\t\tspawn.reborn = true;\r\n\t\t}\r\n\t}\r\n\tif (spawns[0]) {\r\n\t\tgameState.spectator.registerPowerTarget(secret, spawns[0], board, hero, otherHero);\r\n\t}\r\n\tfor (const spawn of spawns) {\r\n\t\tconst impl = cardMappings[spawn.cardId];\r\n\t\tif (hasOnAwaken(impl)) {\r\n\t\t\timpl.onAwaken(spawn, {\r\n\t\t\t\thero,\r\n\t\t\t\tboard,\r\n\t\t\t\totherHero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\tgameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\treturn [...spawns];\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"deity.js","sourceRoot":"","sources":["../../src/simulation/deity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Deity / BG_OldGod secret.\r\n * After 3 friendly Aberrations die each combat, awaken C'Thun or Y'Shaarj with stored stats.\r\n * scriptDataNum1 = deaths remaining, tags BACON_OLD_GOD_ATTACK/HEALTH = atk/hp, scriptDataNum6 = deity dbfId.\r\n */\r\nimport { AllCardsService, GameTag, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { hasOnAwaken } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { getPlayerState, hasCorrectTribe, hasEntityMechanic, hasMechanic } from '../utils';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const isDeityCard = (cardId: string, allCards: AllCardsService): boolean => {\r\n\treturn hasMechanic(allCards.getCard(cardId), GameTag.BACON_OLD_GOD);\r\n};\r\n\r\nexport const isAberration = (entity: BoardEntity, hero: BgsPlayerEntity, gameState: FullGameState): boolean => {\r\n\treturn hasCorrectTribe(entity, hero, Race.ABERRATION, gameState.anomalies, gameState.allCards);\r\n};\r\n\r\nexport const getDeitySecret = (hero: BgsPlayerEntity): BoardSecret | undefined => {\r\n\treturn hero.secrets?.find((s) => s.cardId === CardIds.SecretDeityDnt_BG_OldGod);\r\n};\r\n\r\nexport const getOnBoardDeity = (board: BoardEntity[], allCards: AllCardsService): BoardEntity | undefined => {\r\n\treturn board.find(\r\n\t\t(e) => hasEntityMechanic(e, GameTag.BACON_OLD_GOD, allCards) && e.health > 0 && !e.definitelyDead,\r\n\t);\r\n};\r\n\r\nconst awakeningSecrets = new WeakSet<BoardSecret>();\r\n/** Entities whose attack/health were just set to the stored aura. The next aura pass must not add them again. */\r\nconst deityBaseStatsAssigned = new WeakSet<BoardEntity>();\r\n\r\nconst readSecretAttack = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ?? secret.scriptDataNum2 ?? 1;\r\n};\r\n\r\nconst readSecretHealth = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ?? secret.scriptDataNum3 ?? 1;\r\n};\r\n\r\nconst writeSecretStats = (secret: BoardSecret, attack: number, health: number): void => {\r\n\tsecret.scriptDataNum2 = attack;\r\n\tsecret.scriptDataNum3 = health;\r\n\tsecret.tags = secret.tags ?? {};\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n};\r\n\r\nexport const getDeityBaseStats = (hero: BgsPlayerEntity, entity?: BoardEntity): { attack: number; health: number } => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tconst attack =\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tsecret?.scriptDataNum2 ??\r\n\t\t1;\r\n\tconst health = Math.max(\r\n\t\t1,\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tsecret?.scriptDataNum3 ??\r\n\t\t\t1,\r\n\t);\r\n\treturn { attack, health };\r\n};\r\n\r\n/** Aura captured when this minion was summoned. Later secret growth is a separate buff. */\r\nexport const getDeityAuraSnapshot = (\r\n\tentity: BoardEntity,\r\n\thero: BgsPlayerEntity,\r\n): { attack: number; health: number } => {\r\n\tconst attack = entity.tags?.[GameTag.BACON_OLD_GOD_ATTACK];\r\n\tconst health = entity.tags?.[GameTag.BACON_OLD_GOD_HEALTH];\r\n\tif (attack != null && health != null) {\r\n\t\treturn { attack, health: Math.max(1, health) };\r\n\t}\r\n\treturn getDeityBaseStats(hero, entity);\r\n};\r\n\r\n/** Freeze the current secret onto a deity that is already in play, before combat buffs change it. */\r\nexport const stampOnBoardDeityAuras = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n): void => {\r\n\tfor (const entity of board) {\r\n\t\tif (!isDeityCard(entity.cardId, allCards)) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (\r\n\t\t\tentity.tags?.[GameTag.BACON_OLD_GOD_ATTACK] != null &&\r\n\t\t\tentity.tags?.[GameTag.BACON_OLD_GOD_HEALTH] != null\r\n\t\t) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tconst { attack, health } = getDeityBaseStats(hero, entity);\r\n\t\tentity.tags = entity.tags ?? {};\r\n\t\tentity.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\t\tentity.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n\t}\r\n};\r\n\r\nexport const applyDeityBaseStats = (entity: BoardEntity, hero: BgsPlayerEntity): void => {\r\n\tconst { attack, health } = getDeityBaseStats(hero, entity);\r\n\tentity.attack = attack;\r\n\tentity.maxAttack = attack;\r\n\tentity.health = health;\r\n\tentity.maxHealth = health;\r\n\tentity.tags = entity.tags ?? {};\r\n\tentity.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tentity.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n\tdeityBaseStatsAssigned.add(entity);\r\n};\r\n\r\n/** True once, for the aura pass that follows a fresh stat assignment (awaken, reborn). */\r\nexport const consumeDeityBaseStatsAssignment = (entity: BoardEntity): boolean => {\r\n\tif (!deityBaseStatsAssigned.has(entity)) {\r\n\t\treturn false;\r\n\t}\r\n\tdeityBaseStatsAssigned.delete(entity);\r\n\treturn true;\r\n};\r\n\r\nexport const buffYourDeity = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity | BoardSecret | BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst onBoard = getOnBoardDeity(board, gameState.allCards);\r\n\tif (onBoard) {\r\n\t\tmodifyStats(onBoard, source as BoardEntity, attack, health, board, hero, gameState);\r\n\t}\r\n\tincrementDeitySecretStats(hero, attack, health);\r\n};\r\n\r\nexport const incrementDeitySecretStats = (hero: BgsPlayerEntity, attack: number, health: number): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (secret) {\r\n\t\twriteSecretStats(secret, readSecretAttack(secret) + attack, readSecretHealth(secret) + health);\r\n\t}\r\n};\r\n\r\nexport const buffTeamDeities = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tbuffYourDeity(hero, board, source, attack, health, gameState);\r\n\tconst playerState = getPlayerState(gameState.gameState, hero);\r\n\tconst teammate = playerState?.teammate;\r\n\tif (teammate?.player) {\r\n\t\tbuffYourDeity(teammate.player, teammate.board ?? [], source, attack, health, gameState);\r\n\t}\r\n};\r\n\r\nconst resolveDeityCardId = (secret: BoardSecret, gameState: FullGameState): string => {\r\n\tconst dbfId = secret.scriptDataNum6 ?? secret.tags?.[GameTag.BACON_GLOBAL_OLD_GOD_DBID];\r\n\tif (dbfId) {\r\n\t\tconst fromDbf = gameState.allCards.getCardFromDbfId(dbfId);\r\n\t\tif (fromDbf?.id) {\r\n\t\t\treturn fromDbf.id;\r\n\t\t}\r\n\t}\r\n\treturn CardIds.Cthun_BGFYM_000;\r\n};\r\n\r\nexport const onFriendlyAberrationDied = (\r\n\tdeadEntity: BoardEntity,\r\n\t_deadEntityIndexFromRight: number,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): BoardEntity[] => {\r\n\tif (!isAberration(deadEntity, hero, gameState)) {\r\n\t\treturn [];\r\n\t}\r\n\t// 2026-09-22: This seems to be an HS bug, but for now the deity doesn't spawn when facing the ghost\r\n\t// Looks like this is an intermittent bug\r\n\t// if (hero.hpLeft <= 0 || hero.cardId === CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad) {\r\n\t// \treturn [];\r\n\t// }\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (!secret || secret.triggered || awakeningSecrets.has(secret)) {\r\n\t\treturn [];\r\n\t}\r\n\tconst remaining = (secret.scriptDataNum1 || 3) - 1;\r\n\tsecret.scriptDataNum1 = remaining;\r\n\tif (remaining > 0) {\r\n\t\treturn [];\r\n\t}\r\n\t// A full board skips this awaken. The next friendly Aberration death tries again.\r\n\tif (board.length >= 7) {\r\n\t\tretryDeityAwakenOnNextAberrationDeath(hero);\r\n\t\treturn [];\r\n\t}\r\n\t// Keep the secret visible in the replay until the summon action is recorded.\r\n\tawakeningSecrets.add(secret);\r\n\tconst cardId = resolveDeityCardId(secret, gameState);\r\n\tconst spawns = spawnEntities(\r\n\t\tcardId,\r\n\t\t1,\r\n\t\tboard,\r\n\t\thero,\r\n\t\totherBoard,\r\n\t\totherHero,\r\n\t\tgameState,\r\n\t\tdeadEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t);\r\n\tfor (const spawn of spawns) {\r\n\t\tapplyDeityBaseStats(spawn, hero);\r\n\t\tif (hero.trinkets?.some((t) => t.cardId === CardIds.EvilExperiment_BG36_MagicItem_416)) {\r\n\t\t\tspawn.reborn = true;\r\n\t\t}\r\n\t}\r\n\tif (spawns[0]) {\r\n\t\tgameState.spectator.registerPowerTarget(secret, spawns[0], board, hero, otherHero);\r\n\t}\r\n\tfor (const spawn of spawns) {\r\n\t\tconst impl = cardMappings[spawn.cardId];\r\n\t\tif (hasOnAwaken(impl)) {\r\n\t\t\timpl.onAwaken(spawn, {\r\n\t\t\t\thero,\r\n\t\t\t\tboard,\r\n\t\t\t\totherHero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\tgameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tif (!spawns.length) {\r\n\t\tsecret.triggered = true;\r\n\t}\r\n\treturn [...spawns];\r\n};\r\n\r\nexport const markDeitySecretTriggered = (hero: BgsPlayerEntity): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (secret) {\r\n\t\tsecret.triggered = true;\r\n\t}\r\n};\r\n\r\n/** Board was full, so this awaken did not happen. The next Aberration death starts the summon again. */\r\nexport const retryDeityAwakenOnNextAberrationDeath = (hero: BgsPlayerEntity): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (!secret) {\r\n\t\treturn;\r\n\t}\r\n\tawakeningSecrets.delete(secret);\r\n\tsecret.triggered = false;\r\n\tsecret.scriptDataNum1 = 1;\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 [
|
|
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":"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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 [\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);
|