@firestone-hs/simulate-bgs-battle 1.1.650 → 1.1.652
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/bgs-battle-options.d.ts +1 -0
- package/dist/bgs-battle-options.js.map +1 -1
- package/dist/cards/impl/_card-mappings.js +1 -1
- package/dist/cards/impl/_card-mappings.js.map +1 -1
- package/dist/cards/impl/hero-power/fragrant-phylactery-enchantment.js +1 -1
- package/dist/cards/impl/hero-power/fragrant-phylactery-enchantment.js.map +1 -1
- package/dist/cards/impl/minion/colossus.js +1 -1
- package/dist/cards/impl/minion/colossus.js.map +1 -1
- package/dist/cards/impl/minion/expert-technician.js +5 -1
- package/dist/cards/impl/minion/expert-technician.js.map +1 -1
- package/dist/cards/impl/minion/fauna-whisperer.js +9 -12
- package/dist/cards/impl/minion/fauna-whisperer.js.map +1 -1
- package/dist/cards/impl/minion/fire-forged-evoker.js +1 -2
- package/dist/cards/impl/minion/fire-forged-evoker.js.map +1 -1
- package/dist/cards/impl/minion/geared-guard.js +3 -1
- package/dist/cards/impl/minion/geared-guard.js.map +1 -1
- package/dist/cards/impl/minion/goldrinn-the-great-wolf.js +1 -1
- package/dist/cards/impl/minion/goldrinn-the-great-wolf.js.map +1 -1
- package/dist/cards/impl/minion/lord-of-the-ruins.js +1 -1
- package/dist/cards/impl/minion/lord-of-the-ruins.js.map +1 -1
- package/dist/cards/impl/minion/mutalisk.js +1 -1
- package/dist/cards/impl/minion/mutalisk.js.map +1 -1
- package/dist/cards/impl/minion/noisul-of-the-many-faces.js +1 -1
- package/dist/cards/impl/minion/noisul-of-the-many-faces.js.map +1 -1
- package/dist/cards/impl/minion/oranomonos-the-wilted.js +1 -1
- package/dist/cards/impl/minion/oranomonos-the-wilted.js.map +1 -1
- package/dist/cards/impl/minion/shadowy-construct.d.ts +1 -1
- package/dist/cards/impl/minion/shadowy-construct.js +5 -3
- package/dist/cards/impl/minion/shadowy-construct.js.map +1 -1
- package/dist/cards/impl/minion/young-murk-eye.js +5 -2
- package/dist/cards/impl/minion/young-murk-eye.js.map +1 -1
- package/dist/cards/impl/minion/zergling.js +1 -1
- package/dist/cards/impl/minion/zergling.js.map +1 -1
- package/dist/cards/impl/trinket/eternal-portrait.d.ts +1 -1
- package/dist/cards/impl/trinket/eternal-portrait.js +1 -1
- package/dist/cards/impl/trinket/eternal-portrait.js.map +1 -1
- package/dist/simulate-bgs-battle.js +10 -9
- package/dist/simulate-bgs-battle.js.map +1 -1
- package/dist/simulation/deathrattle-effects.js +2 -2
- package/dist/simulation/deathrattle-effects.js.map +1 -1
- package/dist/simulation/deathrattle-orchestration.js.map +1 -1
- package/dist/simulation/deathrattle-spawns.js +12 -10
- package/dist/simulation/deathrattle-spawns.js.map +1 -1
- package/dist/simulation/spawn-fail.js +1 -1
- package/dist/simulation/spawn-fail.js.map +1 -1
- package/dist/simulation/start-of-combat/soc-illidan-hero-power.js +2 -0
- package/dist/simulation/start-of-combat/soc-illidan-hero-power.js.map +1 -1
- package/dist/simulation/summon-when-space.js +3 -0
- package/dist/simulation/summon-when-space.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"young-murk-eye.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/young-murk-eye.ts"],"names":[],"mappings":";;;AACA,iEAA6D;AAE7D,uDAA2D;AAC3D,iEAAmE;AACnE,0CAAoE;
|
|
1
|
+
{"version":3,"file":"young-murk-eye.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/young-murk-eye.ts"],"names":[],"mappings":";;;AACA,iEAA6D;AAE7D,uDAA2D;AAC3D,iEAAmE;AACnE,0CAAoE;AAEpE,mDAAqD;AAExC,QAAA,YAAY,GAAkB;IAC1C,OAAO,EAAE,0BAAgE;IACzE,SAAS,EAAE,CAAC,MAAmB,EAAE,KAAqB,EAAE,EAAE;QACzD,MAAM,aAAa,GAAG,IAAA,sBAAa,EAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAClG,IAAA,yBAAiB,EAAC,CAAC,EAAE,wBAAO,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CACjE,CAAC;QAIF,MAAM,UAAU,GACf,MAAM,CAAC,MAAM,iBAAoC;YAChD,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,CAAC,IAAA,kBAAU,EAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,iBAAoC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE;YAC9B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;gBACnC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,MAAM,EACN,SAAS,EACT,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,IAAA,8BAAgB,EACf,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,IAAI,EACV,SAAS,EACT,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,SAAS,CACf,CAAC;aACF;SACD;IACF,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '../../../services/card-ids';\r\nimport { GameTag, Race } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { getNeighbours } from '../../../simulation/attack';\r\nimport { triggerBattlecry } from '../../../simulation/battlecries';\r\nimport { hasCorrectTribe, hasEntityMechanic } from '../../../utils';\r\nimport { EndOfTurnCard, EndOfTurnInput } from '../../card.interface';\r\nimport { pickRandom } from '../../../services/utils';\r\n\r\nexport const YoungMurkEye: EndOfTurnCard = {\r\n\tcardIds: [CardIds.YoungMurkEye_BG22_403, CardIds.YoungMurkEye_BG22_403_G],\r\n\tendOfTurn: (minion: BoardEntity, input: EndOfTurnInput) => {\r\n\t\tconst allNeighbours = getNeighbours(input.board, minion, input.board.indexOf(minion)).filter((e) =>\r\n\t\t\thasEntityMechanic(e, GameTag.BATTLECRY, input.gameState.allCards),\r\n\t\t);\r\n\t\t// const validNeighbors = allNeighbours.filter((e) =>\r\n\t\t// \thasCorrectTribe(e, input.hero, Race.MURLOC, input.gameState.anomalies, input.gameState.allCards),\r\n\t\t// );\r\n\t\tconst neighbours =\r\n\t\t\tminion.cardId === CardIds.YoungMurkEye_BG22_403_G\r\n\t\t\t\t? allNeighbours\r\n\t\t\t\t: [pickRandom(allNeighbours)].filter((e) => !!e);\r\n\t\tconst mult = minion.cardId === CardIds.YoungMurkEye_BG22_403_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < mult; i++) {\r\n\t\t\tfor (const neighbour of neighbours) {\r\n\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tminion,\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tinput.board,\r\n\t\t\t\t\tinput.hero,\r\n\t\t\t\t\tinput.otherHero,\r\n\t\t\t\t);\r\n\t\t\t\ttriggerBattlecry(\r\n\t\t\t\t\tinput.board,\r\n\t\t\t\t\tinput.hero,\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tinput.otherBoard,\r\n\t\t\t\t\tinput.otherHero,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
|
@@ -20,7 +20,7 @@ exports.Zergling = {
|
|
|
20
20
|
hasTriggered = true;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
return { hasTriggered: hasTriggered, shouldRecomputeCurrentAttacker:
|
|
23
|
+
return { hasTriggered: hasTriggered, shouldRecomputeCurrentAttacker: true };
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
//# sourceMappingURL=zergling.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zergling.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/zergling.ts"],"names":[],"mappings":";;;AAEA,iFAA8E;AAC9E,+EAAuE;AACvE,uDAAiE;AAEjE,0CAA4C;AAG/B,QAAA,QAAQ,GAAsB;IAC1C,OAAO,EAAE,wCAAiG;IAC1G,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;QACvD,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,wBAAuC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;gBACjC,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,MAAM,CAAC,CAAC;gBAChC,IAAA,yCAAmB,EAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;gBAClF,MAAM,UAAU,GAAG,IAAA,kCAAa,EAC/B,IAAI,CAAC,MAAM,EACX,CAAC,EACD,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,YAAY,CAAC,QAAQ,EAC3B,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,CACJ,CAAC;gBACF,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxF,MAAM,MAAM,GAAG,IAAA,4BAAmB,EACjC,UAAU,EACV,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,YAAY,EAClB,cAAc,EACd,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,YAAY,GAAG,IAAI,CAAC;aACpB;SACD;
|
|
1
|
+
{"version":3,"file":"zergling.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/zergling.ts"],"names":[],"mappings":";;;AAEA,iFAA8E;AAC9E,+EAAuE;AACvE,uDAAiE;AAEjE,0CAA4C;AAG/B,QAAA,QAAQ,GAAsB;IAC1C,OAAO,EAAE,wCAAiG;IAC1G,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;QACvD,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,wBAAuC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;gBACjC,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,MAAM,CAAC,CAAC;gBAChC,IAAA,yCAAmB,EAAC,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;gBAClF,MAAM,UAAU,GAAG,IAAA,kCAAa,EAC/B,IAAI,CAAC,MAAM,EACX,CAAC,EACD,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,YAAY,CAAC,QAAQ,EAC3B,KAAK,EACL,KAAK,EACL,KAAK,EACL,IAAI,CACJ,CAAC;gBACF,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxF,MAAM,MAAM,GAAG,IAAA,4BAAmB,EACjC,UAAU,EACV,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,YAAY,EAClB,cAAc,EACd,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,YAAY,GAAG,IAAI,CAAC;aACpB;SACD;QAID,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;IAC7E,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { removeAurasFromSelf } from '../../../simulation/add-minion-to-board';\r\nimport { spawnEntities } from '../../../simulation/deathrattle-spawns';\r\nimport { performEntitySpawns } from '../../../simulation/spawns';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { copyEntity } from '../../../utils';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const Zergling: StartOfCombatCard = {\r\n\tcardIds: [CardIds.KerriganQueenOfBlades_ZerglingToken_BG31_HERO_811t2, CardIds.Zergling_BG31_HERO_811t2_G],\r\n\tstartOfCombat: (minion: BoardEntity, input: SoCInput) => {\r\n\t\tlet hasTriggered = false;\r\n\t\tconst loops = minion.cardId === CardIds.Zergling_BG31_HERO_811t2_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < loops; i++) {\r\n\t\t\tif (input.playerBoard.length < 7) {\r\n\t\t\t\tconst copy = copyEntity(minion);\r\n\t\t\t\tremoveAurasFromSelf(copy, input.playerBoard, input.playerEntity, input.gameState);\r\n\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\tcopy.cardId,\r\n\t\t\t\t\t1,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\tinput.playerEntity.friendly,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tcopy,\r\n\t\t\t\t);\r\n\t\t\t\tconst indexFromRight = input.playerBoard.length - input.playerBoard.indexOf(minion) - 1;\r\n\t\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\t\tnewMinions,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t\thasTriggered = true;\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Doesn't recompute the first attacker:\r\n\t\t// https://replays.firestoneapp.com/?reviewId=3cdf06e9-192d-49be-b1f8-e47e46704b2b&turn=9&action=0\r\n\t\t// 34.0 It now does https://replays.firestoneapp.com/?reviewId=c85091fd-0f10-4ada-8f11-d6f918d66688&turn=7&action=0\r\n\t\treturn { hasTriggered: hasTriggered, shouldRecomputeCurrentAttacker: true };\r\n\t},\r\n};\r\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BoardTrinket } from '../../../bgs-player-entity';
|
|
2
2
|
import { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';
|
|
3
|
-
export declare const eternalKnightAttack =
|
|
3
|
+
export declare const eternalKnightAttack = 3;
|
|
4
4
|
export declare const eternalKnightHealth = 1;
|
|
5
5
|
export declare const EternalPortrait: {
|
|
6
6
|
startOfCombat: (trinket: BoardTrinket, input: SoCInput) => boolean;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.EternalPortrait = exports.eternalKnightHealth = exports.eternalKnightAttack = void 0;
|
|
4
4
|
const reborn_1 = require("../../../keywords/reborn");
|
|
5
5
|
const taunt_1 = require("../../../keywords/taunt");
|
|
6
|
-
exports.eternalKnightAttack =
|
|
6
|
+
exports.eternalKnightAttack = 3;
|
|
7
7
|
exports.eternalKnightHealth = 1;
|
|
8
8
|
exports.EternalPortrait = {
|
|
9
9
|
startOfCombat: (trinket, input) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eternal-portrait.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/eternal-portrait.ts"],"names":[],"mappings":";;;AAEA,qDAAwD;AACxD,mDAAsD;AAGzC,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,mBAAmB,GAAG,CAAC,CAAC;AAExB,QAAA,eAAe,GAAG;IAC9B,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW;aAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAmC,IAAI,CAAC,CAAC,MAAM,iBAAqC,CAAC;aAC3G,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,EAAE;YACvB,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC7B,IAAA,mBAAW,EAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;gBACxG,IAAA,qBAAY,EACX,MAAM,EACN,IAAI,EACJ,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,KAAK,CAAC,YAAY,EAClB,MAAM,EACN,KAAK,CAAC,WAAW,EACjB,IAAI,EACJ,IAAI,CACJ,CAAC;YACH,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;SACZ;IACF,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '../../../services/card-ids';\r\nimport { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { updateReborn } from '../../../keywords/reborn';\r\nimport { updateTaunt } from '../../../keywords/taunt';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\n\r\nexport const eternalKnightAttack =
|
|
1
|
+
{"version":3,"file":"eternal-portrait.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/eternal-portrait.ts"],"names":[],"mappings":";;;AAEA,qDAAwD;AACxD,mDAAsD;AAGzC,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,mBAAmB,GAAG,CAAC,CAAC;AAExB,QAAA,eAAe,GAAG;IAC9B,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW;aAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAmC,IAAI,CAAC,CAAC,MAAM,iBAAqC,CAAC;aAC3G,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,EAAE;YACvB,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC7B,IAAA,mBAAW,EAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;gBACxG,IAAA,qBAAY,EACX,MAAM,EACN,IAAI,EACJ,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;gBACF,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,KAAK,CAAC,YAAY,EAClB,MAAM,EACN,KAAK,CAAC,WAAW,EACjB,IAAI,EACJ,IAAI,CACJ,CAAC;YACH,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;SACZ;IACF,CAAC;CACD,CAAC","sourcesContent":["import { CardIds } from '../../../services/card-ids';\r\nimport { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { updateReborn } from '../../../keywords/reborn';\r\nimport { updateTaunt } from '../../../keywords/taunt';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\n\r\nexport const eternalKnightAttack = 3;\r\nexport const eternalKnightHealth = 1;\r\n\r\nexport const EternalPortrait = {\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tconst candidates = input.playerBoard\r\n\t\t\t.filter((e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G)\r\n\t\t\t.filter((e) => !e.taunt || !e.reborn);\r\n\t\tif (candidates?.length) {\r\n\t\t\tcandidates.forEach((knight) => {\r\n\t\t\t\tupdateTaunt(knight, true, input.playerBoard, input.playerEntity, input.opponentEntity, input.gameState);\r\n\t\t\t\tupdateReborn(\r\n\t\t\t\t\tknight,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tknight,\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tnull,\r\n\t\t\t\t\tnull,\r\n\t\t\t\t);\r\n\t\t\t});\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
|
@@ -40,17 +40,18 @@ exports.default = async (event) => {
|
|
|
40
40
|
return response;
|
|
41
41
|
};
|
|
42
42
|
const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
43
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
43
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
44
44
|
if (!((_a = cards === null || cards === void 0 ? void 0 : cards.getCards()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
45
45
|
console.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);
|
|
46
46
|
return null;
|
|
47
47
|
}
|
|
48
48
|
const start = Date.now();
|
|
49
49
|
const maxAcceptableDuration = ((_b = battleInput.options) === null || _b === void 0 ? void 0 : _b.maxAcceptableDuration) || 8000;
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
const
|
|
50
|
+
const hideMaxSimulationDurationWarning = (_d = (_c = battleInput.options) === null || _c === void 0 ? void 0 : _c.hideMaxSimulationDurationWarning) !== null && _d !== void 0 ? _d : false;
|
|
51
|
+
const numberOfSimulations = ((_e = battleInput.options) === null || _e === void 0 ? void 0 : _e.numberOfSimulations) || 8000;
|
|
52
|
+
const intermediateSteps = (_g = (_f = battleInput.options) === null || _f === void 0 ? void 0 : _f.intermediateResults) !== null && _g !== void 0 ? _g : 200;
|
|
53
|
+
const damageConfidence = (_j = (_h = battleInput.options) === null || _h === void 0 ? void 0 : _h.damageConfidence) !== null && _j !== void 0 ? _j : 0.9;
|
|
54
|
+
const includeOutcomeSamples = (_l = (_k = battleInput.options) === null || _k === void 0 ? void 0 : _k.includeOutcomeSamples) !== null && _l !== void 0 ? _l : true;
|
|
54
55
|
const simulationResult = {
|
|
55
56
|
wonLethal: 0,
|
|
56
57
|
won: 0,
|
|
@@ -73,7 +74,7 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
73
74
|
};
|
|
74
75
|
const spectator = new spectator_1.Spectator(includeOutcomeSamples);
|
|
75
76
|
const inputReady = (0, input_sanitation_1.buildFinalInput)(battleInput, cards, cardsData);
|
|
76
|
-
!((
|
|
77
|
+
!((_m = battleInput.options) === null || _m === void 0 ? void 0 : _m.skipInfoLogs) && console.time('simulation');
|
|
77
78
|
const outcomes = {};
|
|
78
79
|
for (let i = 0; i < numberOfSimulations; i++) {
|
|
79
80
|
const input = (0, input_clone_1.cloneInput3)(inputReady);
|
|
@@ -111,7 +112,7 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
111
112
|
};
|
|
112
113
|
const simulator = new simulator_1.Simulator(gameState);
|
|
113
114
|
const battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);
|
|
114
|
-
if (Date.now() - start > maxAcceptableDuration) {
|
|
115
|
+
if (Date.now() - start > maxAcceptableDuration && !hideMaxSimulationDurationWarning) {
|
|
115
116
|
console.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');
|
|
116
117
|
break;
|
|
117
118
|
}
|
|
@@ -130,7 +131,7 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
130
131
|
simulationResult.lost++;
|
|
131
132
|
simulationResult.damageLost += battleResult.damageDealt;
|
|
132
133
|
simulationResult.damageLosts.push(battleResult.damageDealt);
|
|
133
|
-
outcomes[battleResult.damageDealt] = ((
|
|
134
|
+
outcomes[battleResult.damageDealt] = ((_o = outcomes[battleResult.damageDealt]) !== null && _o !== void 0 ? _o : 0) + 1;
|
|
134
135
|
if (battleInput.playerBoard.player.hpLeft &&
|
|
135
136
|
battleResult.damageDealt >= battleInput.playerBoard.player.hpLeft) {
|
|
136
137
|
simulationResult.lostLethal++;
|
|
@@ -146,7 +147,7 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
updateSimulationResult(simulationResult, inputReady, damageConfidence);
|
|
149
|
-
!((
|
|
150
|
+
!((_p = battleInput.options) === null || _p === void 0 ? void 0 : _p.skipInfoLogs) && console.timeEnd('simulation');
|
|
150
151
|
spectator.prune();
|
|
151
152
|
simulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);
|
|
152
153
|
simulationResult.damageWons = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { hasDeathrattleSpawnEnchantment } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { cloneInput3 } from './input-clone';\r\nimport { buildFinalInput } from './input-sanitation';\r\nimport { CardIds } from './services/card-ids';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { FullGameState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\n\r\nlet globalCards = new AllCardsService();\r\n\r\nexport const assignCards = (cards: AllCardsService) => {\r\n\tglobalCards = cards;\r\n};\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tif (!event.body?.length) {\r\n\t\tconsole.warn('missing event body', event);\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tconst cards = globalCards;\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\t// Iterate through all intermediate results to reach the final result\r\n\tlet result = battleIterator.next();\r\n\twhile (!result.done) {\r\n\t\tresult = battleIterator.next();\r\n\t}\r\n\r\n\tconst simulationResult = result.value;\r\n\t// console.debug('simulationResult', simulationResult);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = function* (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): Generator<SimulationResult, SimulationResult, void> {\r\n\tif (!cards?.getCards()?.length) {\r\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\r\n\t\treturn null;\r\n\t}\r\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\r\n\tconst start = Date.now();\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\r\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\r\n\tconst damageConfidence = battleInput.options?.damageConfidence ?? 0.9;\r\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWons: [],\r\n\t\tdamageWon: 0,\r\n\t\tdamageWonRange: null,\r\n\t\tdamageLosts: [],\r\n\t\tdamageLost: 0,\r\n\t\tdamageLostRange: null,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst spectator = new Spectator(includeOutcomeSamples);\r\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst gameState: FullGameState = {\r\n\t\t\tallCards: cards,\r\n\t\t\tcardsData: cardsData,\r\n\t\t\tspectator: spectator,\r\n\t\t\tsharedState: new SharedState(),\r\n\t\t\tcurrentTurn: input.gameState.currentTurn,\r\n\t\t\tvalidTribes: input.gameState.validTribes,\r\n\t\t\tanomalies: input.gameState.anomalies,\r\n\t\t\tgameState: {\r\n\t\t\t\tplayer: {\r\n\t\t\t\t\tplayer: input.playerBoard.player,\r\n\t\t\t\t\tboard: input.playerBoard.board,\r\n\t\t\t\t\tteammate: input.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponent: {\r\n\t\t\t\t\tplayer: input.opponentBoard.player,\r\n\t\t\t\t\tboard: input.opponentBoard.board,\r\n\t\t\t\t\tteammate: input.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\tplayerInitial: {\r\n\t\t\t\t\tplayer: inputClone.playerBoard.player,\r\n\t\t\t\t\tboard: inputClone.playerBoard.board,\r\n\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponentInitial: {\r\n\t\t\t\t\tplayer: inputClone.opponentBoard.player,\r\n\t\t\t\t\tboard: inputClone.opponentBoard.board,\r\n\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t\tconst simulator = new Simulator(gameState);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);\r\n\t\tif (Date.now() - start > maxAcceptableDuration) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageWons.push(battleResult.damageDealt);\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageLosts.push(battleResult.damageDealt);\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\r\n\t\t// Yield intermediate result every 200 iterations\r\n\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\r\n\t\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t\t\tyield simulationResult;\r\n\t\t}\r\n\t}\r\n\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);\r\n\t// Avoid sending this verbose data\r\n\r\n\tsimulationResult.damageWons = [];\r\n\tsimulationResult.damageLosts = [];\r\n\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\r\n\treturn simulationResult;\r\n};\r\n\r\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo, damageConfidence: number) => {\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tconst totalDamageWon = simulationResult.damageWons.reduce((a, b) => a + b, 0);\r\n\tconst totalDamageLost = simulationResult.damageLosts.reduce((a, b) => a + b, 0);\r\n\tconst damageWonRange = calculateDamageRange(simulationResult.damageWons, damageConfidence);\r\n\tconst damageLostRange = calculateDamageRange(simulationResult.damageLosts, damageConfidence);\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? totalDamageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost ? totalDamageLost / simulationResult.lost : 0;\r\n\tsimulationResult.damageWonRange = simulationResult.won ? damageWonRange : null;\r\n\tsimulationResult.damageLostRange = simulationResult.lost ? damageLostRange : null;\r\n\r\n\tif (\r\n\t\tsimulationResult.averageDamageWon > 0 &&\r\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage won issue');\r\n\t}\r\n\tif (\r\n\t\tsimulationResult.averageDamageLost > 0 &&\r\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage lost issue');\r\n\t}\r\n};\r\n\r\nconst calculateDamageRange = (damageArray: number[], damageConfidence: number): { min: number; max: number } => {\r\n\tif (damageArray.length === 0) {\r\n\t\treturn { min: 0, max: 0 };\r\n\t}\r\n\r\n\t// Sort the array\r\n\tconst sortedDamage = [...damageArray].sort((a, b) => a - b);\r\n\r\n\t// Calculate the 10th and 90th percentiles\r\n\tconst percentile = (arr: number[], p: number) => {\r\n\t\tconst index = Math.floor(p * arr.length);\r\n\t\treturn arr[index];\r\n\t};\r\n\r\n\tconst minDamage = percentile(sortedDamage, 1 - damageConfidence);\r\n\tconst maxDamage = percentile(sortedDamage, damageConfidence);\r\n\r\n\treturn { min: minDamage, max: maxDamage };\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\n// Used when triggering random deathrattles\r\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\r\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\r\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\r\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\r\n\tCardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172e,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172_Ge,\r\n\tCardIds.TamsinRoame_ImpendingSacrificeEnchantment_BG20_HERO_282e2,\r\n];\r\nconst validDeathrattleEnchantmentsFromMapping = [];\r\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\r\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\r\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\r\n\t\t\t// Also includes non-enchantments, but since we only match this against the enchants list, it's fine\r\n\t\t\tif (hasDeathrattleSpawnEnchantment(cardImpl)) {\r\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\r\n};\r\n\r\n// const cleanEnchantmentsForEntity = (\r\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n// \tentityIds: readonly number[],\r\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n// \treturn enchantments.filter(\r\n// \t\t(enchant) =>\r\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n// \t);\r\n// };\r\n"]}
|
|
1
|
+
{"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { hasDeathrattleSpawnEnchantment } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { cloneInput3 } from './input-clone';\r\nimport { buildFinalInput } from './input-sanitation';\r\nimport { CardIds } from './services/card-ids';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { FullGameState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\n\r\nlet globalCards = new AllCardsService();\r\n\r\nexport const assignCards = (cards: AllCardsService) => {\r\n\tglobalCards = cards;\r\n};\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tif (!event.body?.length) {\r\n\t\tconsole.warn('missing event body', event);\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tconst cards = globalCards;\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\t// Iterate through all intermediate results to reach the final result\r\n\tlet result = battleIterator.next();\r\n\twhile (!result.done) {\r\n\t\tresult = battleIterator.next();\r\n\t}\r\n\r\n\tconst simulationResult = result.value;\r\n\t// console.debug('simulationResult', simulationResult);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = function* (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): Generator<SimulationResult, SimulationResult, void> {\r\n\tif (!cards?.getCards()?.length) {\r\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\r\n\t\treturn null;\r\n\t}\r\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\r\n\tconst start = Date.now();\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst hideMaxSimulationDurationWarning = battleInput.options?.hideMaxSimulationDurationWarning ?? false;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\r\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\r\n\tconst damageConfidence = battleInput.options?.damageConfidence ?? 0.9;\r\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWons: [],\r\n\t\tdamageWon: 0,\r\n\t\tdamageWonRange: null,\r\n\t\tdamageLosts: [],\r\n\t\tdamageLost: 0,\r\n\t\tdamageLostRange: null,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst spectator = new Spectator(includeOutcomeSamples);\r\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\r\n\t\tconst gameState: FullGameState = {\r\n\t\t\tallCards: cards,\r\n\t\t\tcardsData: cardsData,\r\n\t\t\tspectator: spectator,\r\n\t\t\tsharedState: new SharedState(),\r\n\t\t\tcurrentTurn: input.gameState.currentTurn,\r\n\t\t\tvalidTribes: input.gameState.validTribes,\r\n\t\t\tanomalies: input.gameState.anomalies,\r\n\t\t\tgameState: {\r\n\t\t\t\tplayer: {\r\n\t\t\t\t\tplayer: input.playerBoard.player,\r\n\t\t\t\t\tboard: input.playerBoard.board,\r\n\t\t\t\t\tteammate: input.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponent: {\r\n\t\t\t\t\tplayer: input.opponentBoard.player,\r\n\t\t\t\t\tboard: input.opponentBoard.board,\r\n\t\t\t\t\tteammate: input.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\tplayerInitial: {\r\n\t\t\t\t\tplayer: inputClone.playerBoard.player,\r\n\t\t\t\t\tboard: inputClone.playerBoard.board,\r\n\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t\topponentInitial: {\r\n\t\t\t\t\tplayer: inputClone.opponentBoard.player,\r\n\t\t\t\t\tboard: inputClone.opponentBoard.board,\r\n\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t};\r\n\t\tconst simulator = new Simulator(gameState);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);\r\n\t\tif (Date.now() - start > maxAcceptableDuration && !hideMaxSimulationDurationWarning) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageWons.push(battleResult.damageDealt);\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\tsimulationResult.damageLosts.push(battleResult.damageDealt);\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\r\n\t\t// Yield intermediate result every 200 iterations\r\n\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\r\n\t\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t\t\tyield simulationResult;\r\n\t\t}\r\n\t}\r\n\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);\r\n\t// Avoid sending this verbose data\r\n\r\n\tsimulationResult.damageWons = [];\r\n\tsimulationResult.damageLosts = [];\r\n\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\r\n\treturn simulationResult;\r\n};\r\n\r\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo, damageConfidence: number) => {\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tconst totalDamageWon = simulationResult.damageWons.reduce((a, b) => a + b, 0);\r\n\tconst totalDamageLost = simulationResult.damageLosts.reduce((a, b) => a + b, 0);\r\n\tconst damageWonRange = calculateDamageRange(simulationResult.damageWons, damageConfidence);\r\n\tconst damageLostRange = calculateDamageRange(simulationResult.damageLosts, damageConfidence);\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? totalDamageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost ? totalDamageLost / simulationResult.lost : 0;\r\n\tsimulationResult.damageWonRange = simulationResult.won ? damageWonRange : null;\r\n\tsimulationResult.damageLostRange = simulationResult.lost ? damageLostRange : null;\r\n\r\n\tif (\r\n\t\tsimulationResult.averageDamageWon > 0 &&\r\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage won issue');\r\n\t}\r\n\tif (\r\n\t\tsimulationResult.averageDamageLost > 0 &&\r\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\r\n\t) {\r\n\t\tconsole.warn('average damage lost issue');\r\n\t}\r\n};\r\n\r\nconst calculateDamageRange = (damageArray: number[], damageConfidence: number): { min: number; max: number } => {\r\n\tif (damageArray.length === 0) {\r\n\t\treturn { min: 0, max: 0 };\r\n\t}\r\n\r\n\t// Sort the array\r\n\tconst sortedDamage = [...damageArray].sort((a, b) => a - b);\r\n\r\n\t// Calculate the 10th and 90th percentiles\r\n\tconst percentile = (arr: number[], p: number) => {\r\n\t\tconst index = Math.floor(p * arr.length);\r\n\t\treturn arr[index];\r\n\t};\r\n\r\n\tconst minDamage = percentile(sortedDamage, 1 - damageConfidence);\r\n\tconst maxDamage = percentile(sortedDamage, damageConfidence);\r\n\r\n\treturn { min: minDamage, max: maxDamage };\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\n// Used when triggering random deathrattles\r\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\r\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\r\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\r\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\r\n\tCardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172e,\r\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172_Ge,\r\n\tCardIds.TamsinRoame_ImpendingSacrificeEnchantment_BG20_HERO_282e2,\r\n];\r\nconst validDeathrattleEnchantmentsFromMapping = [];\r\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\r\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\r\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\r\n\t\t\t// Also includes non-enchantments, but since we only match this against the enchants list, it's fine\r\n\t\t\tif (hasDeathrattleSpawnEnchantment(cardImpl)) {\r\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\r\n};\r\n\r\n// const cleanEnchantmentsForEntity = (\r\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n// \tentityIds: readonly number[],\r\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n// \treturn enchantments.filter(\r\n// \t\t(enchant) =>\r\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n// \t);\r\n// };\r\n"]}
|
|
@@ -129,7 +129,7 @@ const handleWheneverMinionsKillEffectForBoard = (board, hero, otherBoard, otherH
|
|
|
129
129
|
.filter((e) => e.health > 0 && !e.definitelyDead)
|
|
130
130
|
.forEach((icesnarl) => {
|
|
131
131
|
const mult = icesnarl.cardId === "BG20_HERO_100_Buddy_G" ? 2 : 1;
|
|
132
|
-
(0, stats_1.modifyStats)(icesnarl, icesnarl, 0,
|
|
132
|
+
(0, stats_1.modifyStats)(icesnarl, icesnarl, 0, 3 * mult, board, hero, gameState);
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
135
|
}
|
|
@@ -315,7 +315,7 @@ const rememberDeathrattles = (fish, inputDeadEntities, cardsData, allCards, shar
|
|
|
315
315
|
.flatMap((e) => e.rememberedDeathrattles)) !== null && _b !== void 0 ? _b : [];
|
|
316
316
|
const newDeathrattles = [...validDeathrattles, ...validEnchantments, ...deadEntityRememberedDeathrattles];
|
|
317
317
|
if (newDeathrattles.length > 0) {
|
|
318
|
-
if ((0, utils_2.isGolden)(fish.cardId, allCards)) {
|
|
318
|
+
if ((0, utils_2.isFish)(fish) && (0, utils_2.isGolden)(fish.cardId, allCards)) {
|
|
319
319
|
const doubleDr = newDeathrattles.reduce((res, current) => res.concat([current, current]), []);
|
|
320
320
|
fish.rememberedDeathrattles = [...(fish.rememberedDeathrattles || []), ...doubleDr];
|
|
321
321
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deathrattle-effects.js","sourceRoot":"","sources":["../../src/simulation/deathrattle-effects.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\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 { CardsData } from '../cards/cards-data';\r\nimport { eternalKnightAttack, eternalKnightHealth } from '../cards/impl/trinket/eternal-portrait';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { updateTaunt } from '../keywords/taunt';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickMultipleRandomDifferent } from '../services/utils';\r\nimport { isValidDeathrattleEnchantment } from '../simulate-bgs-battle';\r\nimport {\r\n\tgetRandomMinionWithHighestHealth,\r\n\tgrantRandomStats,\r\n\thasCorrectTribe,\r\n\tisDead,\r\n\tisFish,\r\n\tisGolden,\r\n} from '../utils';\r\nimport { dealDamageToMinion } from './attack';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { groupLeapfroggerDeathrattles } from './remembered-deathrattle';\r\nimport { SharedState } from './shared-state';\r\nimport { modifyStats } from './stats';\r\n\r\nconst DEATHRATTLES_REQUIRE_MEMORY = [CardIds.StitchedSalvager_BG31_999, CardIds.StitchedSalvager_BG31_999_G];\r\n\r\nexport const computeDeathrattleMultiplier = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tsharedState: SharedState,\r\n): number => {\r\n\tconst rivendare =\r\n\t\t!!board.find(\r\n\t\t\t(entity) =>\r\n\t\t\t\tentity.cardId === CardIds.BaronRivendare_BG_FP1_031 ||\r\n\t\t\t\tentity.cardId === CardIds.MoiraBronzebeard_BG27_518,\r\n\t\t) || boardHero.secrets?.some((e) => e.cardId === CardIds.TitusTribute_BG28_843);\r\n\tconst goldenRivendare = board.find(\r\n\t\t(entity) =>\r\n\t\t\tentity.cardId === CardIds.BaronRivendare_TB_BaconUps_055 ||\r\n\t\t\tentity.cardId === CardIds.MoiraBronzebeard_BG27_518_G,\r\n\t);\r\n\tconst titus = board.filter((entity) => entity.cardId === CardIds.TitusRivendare_BG25_354).length;\r\n\tconst goldenTitus = board.filter((entity) => entity.cardId === CardIds.TitusRivendare_BG25_354_G).length;\r\n\tconst deathlyPhylacteries = boardHero.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.DeathlyPhylactery_BG30_MagicItem_700 && t.scriptDataNum1 > 0,\r\n\t).length;\r\n\tconst tombs =\r\n\t\tboardHero.questRewardEntities?.filter((entity) => entity.cardId === CardIds.TurbulentTombs)?.length ?? 0;\r\n\tconst echoesOfArgus = sharedState.anomalies.includes(CardIds.EchoesOfArgus_BG27_Anomaly_802) ? 1 : 0;\r\n\tconst scourgeMultiplier = deadEntity.additionalCards?.includes(CardIds.ScourgeTroll) ? 2 : 1;\r\n\r\n\tconst multiplier =\r\n\t\tscourgeMultiplier *\r\n\t\t((goldenRivendare ? 3 : rivendare ? 2 : 1) +\r\n\t\t\tdeathlyPhylacteries +\r\n\t\t\ttitus +\r\n\t\t\t2 * goldenTitus +\r\n\t\t\ttombs +\r\n\t\t\techoesOfArgus);\r\n\treturn multiplier;\r\n};\r\n\r\nexport const applyLightningInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity | BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// Because the golden version doubles all the remembered effects\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tconst previousVenomous = (deadEntity as BoardEntity).venomous;\r\n\t(deadEntity as BoardEntity).venomous = false;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst targets = pickMultipleRandomDifferent(otherBoard, 5);\r\n\t\tfor (const target of targets) {\r\n\t\t\tdealDamageToMinion(\r\n\t\t\t\ttarget,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherBoardHero,\r\n\t\t\t\tdeadEntity,\r\n\t\t\t\t1,\r\n\t\t\t\tboardWithDeadEntity,\r\n\t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\t(deadEntity as BoardEntity).venomous = previousVenomous;\r\n};\r\n\r\nexport const applyWaterInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity, // Can be null when trinket is used\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst validBoard = boardWithDeadEntity.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\t\tconst target: BoardEntity = validBoard[validBoard.length - 1];\r\n\t\tif (!!target) {\r\n\t\t\tupdateTaunt(target, true, boardWithDeadEntity, boardWithDeadEntityHero, otherHero, gameState);\r\n\t\t\tupdateDivineShield(target, boardWithDeadEntity, boardWithDeadEntityHero, otherHero, true, gameState);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const applyFireInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst target: BoardEntity = boardWithDeadEntity.filter((e) => e.health > 0 && !e.definitelyDead)[0];\r\n\t\tif (!!target) {\r\n\t\t\tmodifyStats(\r\n\t\t\t\ttarget,\r\n\t\t\t\tsourceEntity,\r\n\t\t\t\ttarget.attack,\r\n\t\t\t\t0,\r\n\t\t\t\tboardWithDeadEntity,\r\n\t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const applyEarthInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tdeadEntity: BoardEntity,\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst minionsGrantedDeathrattle: BoardEntity[] = pickMultipleRandomDifferent(boardWithDeadEntity, 4);\r\n\t\tminionsGrantedDeathrattle.forEach((minion) => {\r\n\t\t\tminion.enchantments.push({\r\n\t\t\t\tcardId: CardIds.EarthInvocation_ElementEarthEnchantment,\r\n\t\t\t\toriginEntityId: deadEntity?.entityId,\r\n\t\t\t\ttiming: gameState.sharedState.currentEntityId++,\r\n\t\t\t});\r\n\t\t\tgameState.spectator.registerPowerTarget(sourceEntity, minion, boardWithDeadEntity, null, null);\r\n\t\t});\r\n\t}\r\n};\r\n\r\nexport const applyLeapFroggerEffect = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tisPremium: boolean,\r\n\tgameState: FullGameState,\r\n\tmultiplier: number,\r\n): void => {\r\n\tmultiplier = multiplier ?? deadEntity.deathrattleRepeats ?? 1;\r\n\t// console.debug('applying leapfrogger effect', deadEntity.entityId, multiplier);\r\n\tconst buffed = grantRandomStats(\r\n\t\tdeadEntity,\r\n\t\tboardWithDeadEntity,\r\n\t\tboardWithDeadEntityHero,\r\n\t\tmultiplier * (isPremium ? 2 : 1),\r\n\t\tmultiplier * (isPremium ? 2 : 1),\r\n\t\tRace.BEAST,\r\n\t\tfalse,\r\n\t\tgameState,\r\n\t);\r\n\tif (buffed) {\r\n\t\tbuffed.enchantments.push({\r\n\t\t\tcardId: isPremium\r\n\t\t\t\t? CardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge\r\n\t\t\t\t: CardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\t\t\toriginEntityId: deadEntity.entityId,\r\n\t\t\trepeats: multiplier > 1 ? multiplier : 1,\r\n\t\t\ttiming: gameState.sharedState.currentEntityId++,\r\n\t\t});\r\n\t}\r\n};\r\n\r\nexport const applyRecurringNightmareDeathrattleEffect = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tisPremium: boolean,\r\n\tgameState: FullGameState,\r\n\tmultiplier = 1,\r\n): void => {\r\n\t// multiplier = multiplier || 1;\r\n\t// const target = pickRandom(\r\n\t// \tboardWithDeadEntity\r\n\t// \t\t.filter((e) =>\r\n\t// \t\t\thasCorrectTribe(e, boardWithDeadEntityHero, Race.UNDEAD, gameState.anomalies, gameState.allCards),\r\n\t// \t\t)\r\n\t// \t\t.filter(\r\n\t// \t\t\t(e) =>\r\n\t// \t\t\t\te.cardId !== CardIds.RecurringNightmare_BG26_055 &&\r\n\t// \t\t\t\te.cardId !== CardIds.RecurringNightmare_BG26_055_G,\r\n\t// \t\t),\r\n\t// );\r\n\t// if (target) {\r\n\t// \ttarget.enchantments = target.enchantments ?? [];\r\n\t// \ttarget.enchantments.push({\r\n\t// \t\tcardId: isPremium\r\n\t// \t\t\t? CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge\r\n\t// \t\t\t: CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\t// \t\toriginEntityId: deadEntity.entityId,\r\n\t// \t\trepeats: multiplier > 1 ? multiplier : 1,\r\n\t// \t\ttiming: gameState.sharedState.currentEntityId++,\r\n\t// \t});\r\n\t// \tgameState.spectator.registerPowerTarget(deadEntity, target, boardWithDeadEntity, null, null);\r\n\t// }\r\n};\r\n\r\n// Some minions like Icesnarl can revive themselves when killing a minion, so it needs to be handled before\r\n// we actually make the minion die\r\nexport const handleWheneverMinionsKillEffect = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\thandleWheneverMinionsKillEffectForBoard(board, hero, otherBoard, otherHero, gameState);\r\n\t// It's called once for each board already, so don't duplicate it here\r\n\t// handleWheneverMinionsKillEffectForBoard(otherBoard, otherHero, board, hero, gameState);\r\n};\r\n\r\nconst handleWheneverMinionsKillEffectForBoard = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\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\tconst futureDeadEntity = board[i];\r\n\t\t\tconst killer = futureDeadEntity.lastAffectedByEntity;\r\n\t\t\tif (!killer) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Killed an enemy minion\r\n\t\t\tif (killer.friendly !== futureDeadEntity.friendly) {\r\n\t\t\t\tfor (const heroPower of otherHero.heroPowers) {\r\n\t\t\t\t\t// Can't be used to resurrect a dead minion\r\n\t\t\t\t\t// https://replays.firestoneapp.com/?reviewId=d1fffee8-0bc3-40f5-9a59-85eef8367095&turn=11&action=4\r\n\t\t\t\t\tif (heroPower.cardId === CardIds.Rokara_GloryOfCombat && !isDead(killer)) {\r\n\t\t\t\t\t\tmodifyStats(killer, otherHero, 1, 0, otherBoard, otherHero, gameState);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Icesnarl the Mighty\r\n\t\t\t\totherBoard\r\n\t\t\t\t\t.filter(\r\n\t\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t\te.cardId === CardIds.IcesnarlTheMighty_BG20_HERO_100_Buddy ||\r\n\t\t\t\t\t\t\te.cardId === CardIds.IcesnarlTheMighty_BG20_HERO_100_Buddy_G,\r\n\t\t\t\t\t)\r\n\t\t\t\t\t// Can't be revived\r\n\t\t\t\t\t// 33.6 https://replays.firestoneapp.com/?reviewId=608ddffb-6c04-4def-a8de-fd39228f4de4&turn=11&action=4\r\n\t\t\t\t\t// Maybe should move to an \"after kill\" phase, where dead minions are already dead?\r\n\t\t\t\t\t.filter((e) => e.health > 0 && !e.definitelyDead)\r\n\t\t\t\t\t.forEach((icesnarl) => {\r\n\t\t\t\t\t\tconst mult = icesnarl.cardId === CardIds.IcesnarlTheMighty_BG20_HERO_100_Buddy_G ? 2 : 1;\r\n\t\t\t\t\t\tmodifyStats(icesnarl, icesnarl, 0, 2 * mult, board, hero, gameState);\r\n\t\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const handleAfterMinionKillsEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// Moved to \"whenever kills\", as these can revive the minion that kills\r\n\t// const killer = deadEntity.lastAffectedByEntity;\r\n\t// if (!killer) {\r\n\t// \treturn;\r\n\t// }\r\n\t// // Killed an enemy minion\r\n\t// if (killer.friendly !== deadEntity.friendly) {\r\n\t// }\r\n};\r\n\r\nexport const applyAfterMinionDiesEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.DEMON, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplySoulJugglerEffect(boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState);\r\n\t}\r\n};\r\n\r\nexport const applyWheneverMinionDiesEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// console.log('applying minion death effect', stringifySimpleCard(deadEntity, allCards));\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.BEAST, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplyScavengingHyenaEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.MECH, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplyJunkbotEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.MURLOC, gameState.anomalies, gameState.allCards)) {\r\n\t\tremoveOldMurkEyeAttack(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t\tremoveOldMurkEyeAttack(otherBoard, otherBoardHero, gameState);\r\n\t}\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.ELEMENTAL, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplyMossOfTheSchlossEffect(deadEntity, boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\r\n\tif (deadEntity.taunt) {\r\n\t\tapplyBristlemaneScrapsmithEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t\tapplyQirajiHarbringerEffect(boardWithDeadEntity, boardWithDeadEntityHero, deadEntityIndexFromRight, gameState);\r\n\t}\r\n\r\n\tif (\r\n\t\tdeadEntity.cardId === CardIds.EternalKnight_BG25_008 ||\r\n\t\tdeadEntity.cardId === CardIds.EternalKnight_BG25_008_G\r\n\t) {\r\n\t\tapplyEternalKnightEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\r\n\t// Putricide-only\r\n\tboardWithDeadEntity\r\n\t\t.filter((e) => e.additionalCards?.includes(CardIds.FlesheatingGhoulLegacy_BG26_tt_004))\r\n\t\t.forEach((e) => {\r\n\t\t\tmodifyStats(e, null, 1, 0, boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t\t});\r\n\r\n\tapplyRotHideGnollEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\r\n\t// Overkill\r\n\tif (\r\n\t\tdeadEntity.health < 0 &&\r\n\t\tgameState.sharedState.currentAttackerEntityId != null &&\r\n\t\tgameState.sharedState.currentAttackerEntityId === deadEntity.lastAffectedByEntity?.entityId\r\n\t) {\r\n\t\t// if (deadEntity.lastAffectedByEntity.cardId === CardIds.HeraldOfFlame_BGS_032) {\r\n\t\t// \tconst targets = boardWithDeadEntity.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\t\t// \tif (targets.length > 0) {\r\n\t\t// \t\tconst target = targets[0];\r\n\t\t// \t\tdealDamageToMinion(\r\n\t\t// \t\t\ttarget,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\t3,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tgameState,\r\n\t\t// \t\t);\r\n\t\t// \t}\r\n\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.HeraldOfFlame_TB_BaconUps_103) {\r\n\t\t// \tconst targets = boardWithDeadEntity.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\t\t// \tif (targets.length > 0) {\r\n\t\t// \t\tconst target = targets[0];\r\n\t\t// \t\tdealDamageToMinion(\r\n\t\t// \t\t\ttarget,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\t6,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tgameState,\r\n\t\t// \t\t);\r\n\t\t// \t}\r\n\t\t// }\r\n\t\t// else if (deadEntity.lastAffectedByEntity.cardId === CardIds.WildfireElemental && deadEntity.lastAffectedByEntity.attacking) {\r\n\t\t// \t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.WildfireElemental) {\r\n\t\t// \t// console.log('applying WildfireElemental effect', stringifySimple(boardWithDeadEntity, allCards));\r\n\t\t// \tconst excessDamage = -deadEntity.health;\r\n\t\t// \t// Prevent propagation of the effect\r\n\t\t// \tdeadEntity.lastAffectedByEntity.attacking = false;\r\n\t\t// \tconst neighbours = getNeighbours(boardWithDeadEntity, null, boardWithDeadEntity.length - deadEntityIndexFromRight);\r\n\t\t// \t// console.log('neighbours', stringifySimple(neighbours, allCards));\r\n\t\t// \tif (neighbours.length > 0) {\r\n\t\t// \t\tconst randomTarget = neighbours[Math.floor(Math.random() * neighbours.length)];\r\n\t\t// \t\tdealDamageToEnemy(\r\n\t\t// \t\t\trandomTarget,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\texcessDamage,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tallCards,\r\n\t\t// \t\t\tcardsData,\r\n\t\t// \t\t\tsharedState,\r\n\t\t// \t\t\tspectator,\r\n\t\t// \t\t);\r\n\t\t// \t}\r\n\t\t// } else if (\r\n\t\t// \tdeadEntity.lastAffectedByEntity.cardId === CardIds.WildfireElementalBattlegrounds &&\r\n\t\t// \tdeadEntity.lastAffectedByEntity.attacking\r\n\t\t// ) {\r\n\t\t// \tconst excessDamage = -deadEntity.health;\r\n\t\t// \tdeadEntity.lastAffectedByEntity.attacking = false;\r\n\t\t// \tconst neighbours = getNeighbours(boardWithDeadEntity, null, boardWithDeadEntity.length - deadEntityIndexFromRight);\r\n\t\t// \tneighbours.forEach((neighbour) =>\r\n\t\t// \t\tdealDamageToEnemy(\r\n\t\t// \t\t\tneighbour,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\texcessDamage,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tallCards,\r\n\t\t// \t\t\tcardsData,\r\n\t\t// \t\t\tsharedState,\r\n\t\t// \t\t\tspectator,\r\n\t\t// \t\t),\r\n\t\t// \t);\r\n\t\t// }\r\n\t\tif (deadEntity.lastAffectedByEntity.cardId === CardIds.IronhideDirehorn_TRL_232) {\r\n\t\t\tconst newEntities = spawnEntities(\r\n\t\t\t\tCardIds.IronhideDirehorn_IronhideRuntToken_TRL_232t,\r\n\t\t\t\t1,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherBoardHero,\r\n\t\t\t\tboardWithDeadEntity,\r\n\t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\t!deadEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t);\r\n\t\t\totherBoard.splice(otherBoard.length - deadEntityIndexFromRight, 0, ...newEntities);\r\n\t\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.IronhideDirehorn_TB_BaconUps_051) {\r\n\t\t\t// \tconst newEntities = spawnEntities(\r\n\t\t\t// \t\tCardIds.IronhideDirehorn_IronhideRuntToken_TB_BaconUps_051t,\r\n\t\t\t// \t\t1,\r\n\t\t\t// \t\totherBoard,\r\n\t\t\t// \t\totherBoardHero,\r\n\t\t\t// \t\tboardWithDeadEntity,\r\n\t\t\t// \t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\tgameState,\r\n\t\t\t// \t\t!deadEntity.friendly,\r\n\t\t\t// \t\tfalse,\r\n\t\t\t// \t);\r\n\t\t\t// \totherBoard.splice(otherBoard.length - deadEntityIndexFromRight, 0, ...newEntities);\r\n\t\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.SeabreakerGoliath_BGS_080) {\r\n\t\t\t// \tconst otherPirates = otherBoard\r\n\t\t\t// \t\t.filter((entity) =>\r\n\t\t\t// \t\t\thasCorrectTribe(\r\n\t\t\t// \t\t\t\tentity,\r\n\t\t\t// \t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\t\tRace.PIRATE,\r\n\t\t\t// \t\t\t\tgameState.anomalies,\r\n\t\t\t// \t\t\t\tgameState.allCards,\r\n\t\t\t// \t\t\t),\r\n\t\t\t// \t\t)\r\n\t\t\t// \t\t.filter((entity) => entity.entityId !== deadEntity.lastAffectedByEntity.entityId);\r\n\t\t\t// \totherPirates.forEach((pirate) => {\r\n\t\t\t// \t\tmodifyStats(\r\n\t\t\t// \t\t\tpirate,\r\n\t\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t\t// \t\t\t2,\r\n\t\t\t// \t\t\t2,\r\n\t\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\tgameState,\r\n\t\t\t// \t\t);\r\n\t\t\t// \t});\r\n\t\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.SeabreakerGoliath_TB_BaconUps_142) {\r\n\t\t\t// \tconst otherPirates = otherBoard\r\n\t\t\t// \t\t.filter((entity) =>\r\n\t\t\t// \t\t\thasCorrectTribe(\r\n\t\t\t// \t\t\t\tentity,\r\n\t\t\t// \t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\t\tRace.PIRATE,\r\n\t\t\t// \t\t\t\tgameState.anomalies,\r\n\t\t\t// \t\t\t\tgameState.allCards,\r\n\t\t\t// \t\t\t),\r\n\t\t\t// \t\t)\r\n\t\t\t// \t\t.filter((entity) => entity.entityId !== deadEntity.lastAffectedByEntity.entityId);\r\n\t\t\t// \totherPirates.forEach((pirate) => {\r\n\t\t\t// \t\tmodifyStats(\r\n\t\t\t// \t\t\tpirate,\r\n\t\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t\t// \t\t\t4,\r\n\t\t\t// \t\t\t4,\r\n\t\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\tgameState,\r\n\t\t\t// \t\t);\r\n\t\t\t// \t});\r\n\t\t}\r\n\t}\r\n};\r\n\r\n/** @deprecated */\r\nexport const dealDamageToAllMinions = (\r\n\tboard1: BoardEntity[],\r\n\tboard1Hero: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tboard2Hero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity,\r\n\tdamageDealt: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (board1.length === 0 && board2.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\tfor (let i = 0; i < board1.length; i++) {\r\n\t\tdealDamageToMinion(board1[i], board1, board1Hero, damageSource, damageDealt, board2, board2Hero, gameState);\r\n\t}\r\n\tfor (let i = 0; i < board2.length; i++) {\r\n\t\tdealDamageToMinion(board2[i], board2, board2Hero, damageSource, damageDealt, board1, board1Hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const applySoulJugglerEffect = (\r\n\tboardWithJugglers: BoardEntity[],\r\n\tboardWithJugglersHero: BgsPlayerEntity,\r\n\tboardToAttack: BoardEntity[],\r\n\tboardToAttackHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (boardWithJugglers.length === 0 && boardToAttack.length === 0) {\r\n\t\treturn;\r\n\t\t// return [boardWithJugglers, boardToAttack];\r\n\t}\r\n\tconst jugglers = boardWithJugglers.filter((entity) => entity.cardId === CardIds.SoulJuggler_BGS_002);\r\n\tfor (const juggler of jugglers) {\r\n\t\tconst target = getRandomMinionWithHighestHealth(boardToAttack);\r\n\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\tjuggler,\r\n\t\t\ttarget,\r\n\t\t\tboardWithJugglers,\r\n\t\t\tboardWithJugglersHero,\r\n\t\t\tboardToAttackHero,\r\n\t\t);\r\n\t\tdealDamageToMinion(\r\n\t\t\ttarget,\r\n\t\t\tboardToAttack,\r\n\t\t\tboardToAttackHero,\r\n\t\t\tjuggler,\r\n\t\t\t4,\r\n\t\t\tboardWithJugglers,\r\n\t\t\tboardWithJugglersHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n\tconst goldenJugglers = boardWithJugglers.filter((entity) => entity.cardId === CardIds.SoulJuggler_TB_BaconUps_075);\r\n\tfor (const juggler of goldenJugglers) {\r\n\t\tfor (let i = 0; i < 2; i++) {\r\n\t\t\tconst target = getRandomMinionWithHighestHealth(boardToAttack);\r\n\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\tjuggler,\r\n\t\t\t\ttarget,\r\n\t\t\t\tboardWithJugglers,\r\n\t\t\t\tboardWithJugglersHero,\r\n\t\t\t\tboardToAttackHero,\r\n\t\t\t);\r\n\t\t\tdealDamageToMinion(\r\n\t\t\t\ttarget,\r\n\t\t\t\tboardToAttack,\r\n\t\t\t\tboardToAttackHero,\r\n\t\t\t\tjuggler,\r\n\t\t\t\t4,\r\n\t\t\t\tboardWithJugglers,\r\n\t\t\t\tboardWithJugglersHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\t// processMinionDeath(\r\n\t// \tboardWithJugglers,\r\n\t// \tboardWithJugglersHero,\r\n\t// \tboardToAttack,\r\n\t// \tboardToAttackHero,\r\n\t// \tallCards,\r\n\t// \tcardsData,\r\n\t// \tsharedState,\r\n\t// \tspectator,\r\n\t// );\r\n};\r\n\r\nconst applyScavengingHyenaEffect = (\r\n\tboard: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// const copy = [...board];\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].cardId === CardIds.ScavengingHyenaLegacy_BG_EX1_531) {\r\n\t\t\tmodifyStats(board[i], null, 2, 1, board, boardWithDeadEntityHero, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t} else if (board[i].cardId === CardIds.ScavengingHyenaLegacy_TB_BaconUps_043) {\r\n\t\t\tmodifyStats(board[i], null, 4, 2, board, boardWithDeadEntityHero, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyEternalKnightEffect = (board: BoardEntity[], hero: BgsPlayerEntity, gameState: FullGameState): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (\r\n\t\t\tboard[i].cardId === CardIds.EternalKnight_BG25_008 ||\r\n\t\t\tboard[i].cardId === CardIds.EternalKnight_BG25_008_G\r\n\t\t) {\r\n\t\t\tconst multiplier = board[i].cardId === CardIds.EternalKnight_BG25_008_G ? 2 : 1;\r\n\t\t\tmodifyStats(\r\n\t\t\t\tboard[i],\r\n\t\t\t\tnull,\r\n\t\t\t\tmultiplier * eternalKnightAttack,\r\n\t\t\t\tmultiplier * eternalKnightHealth,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyRotHideGnollEffect = (board: BoardEntity[], hero: BgsPlayerEntity, gameState: FullGameState): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].cardId === CardIds.RotHideGnoll_BG25_013 || board[i].cardId === CardIds.RotHideGnoll_BG25_013_G) {\r\n\t\t\tconst multiplier = board[i].cardId === CardIds.RotHideGnoll_BG25_013_G ? 2 : 1;\r\n\t\t\tmodifyStats(board[i], null, multiplier * 1, 0, board, hero, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyBristlemaneScrapsmithEffect = (\r\n\tboard: BoardEntity[],\r\n\tboardPlayerEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (\r\n\t\t\tboard[i].cardId === CardIds.BristlemaneScrapsmith_BG24_707 ||\r\n\t\t\tboard[i].cardId === CardIds.BristlemaneScrapsmith_BG24_707_G\r\n\t\t) {\r\n\t\t\tconst cardsToAdd = Array(CardIds.BristlemaneScrapsmith_BG24_707_G ? 2 : 1).fill(CardIds.BloodGem);\r\n\t\t\taddCardsInHand(boardPlayerEntity, board, cardsToAdd, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, boardPlayerEntity, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyMossOfTheSchlossEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tboard\r\n\t\t.filter(\r\n\t\t\t(e) => e.cardId === CardIds.MossOfTheSchloss_BG30_111 || e.cardId === CardIds.MossOfTheSchloss_BG30_111_G,\r\n\t\t)\r\n\t\t.filter((e) => e.abiityChargesLeft > 0)\r\n\t\t.forEach((entity) => {\r\n\t\t\tmodifyStats(entity, null, deadEntity.maxAttack, deadEntity.maxHealth, board, hero, gameState);\r\n\t\t\tentity.abiityChargesLeft--;\r\n\t\t\tgameState.spectator.registerPowerTarget(entity, entity, board, null, null);\r\n\t\t});\r\n};\r\n\r\nconst applyJunkbotEffect = (board: BoardEntity[], hero: BgsPlayerEntity, gameState: FullGameState): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].cardId === CardIds.Junkbot_GVG_106) {\r\n\t\t\tmodifyStats(board[i], board[i], 2, 2, board, hero, gameState);\r\n\t\t\t// } else if (board[i].cardId === CardIds.Junkbot_TB_BaconUps_046) {\r\n\t\t\t// \tmodifyStats(board[i], board[i], 4, 4, board, hero, gameState);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyQirajiHarbringerEffect = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// const qiraji = board.filter((entity) => entity.cardId === CardIds.QirajiHarbinger_BGS_112);\r\n\t// const goldenQiraji = board.filter((entity) => entity.cardId === CardIds.QirajiHarbinger_TB_BaconUps_303);\r\n\t// // TODO: if reactivated, properly apply buffs one by one, instead of all together\r\n\t// if (qiraji.length + goldenQiraji.length > 0) {\r\n\t// \tconst neighbours = getNeighbours(board, null, deadEntityIndexFromRight);\r\n\t// \tconst buff = 2 * qiraji.length + 4 * goldenQiraji.length;\r\n\t// \tneighbours.forEach((entity) => {\r\n\t// \t\tmodifyStats(entity, null, buff, buff, board, hero, gameState);\r\n\t// \t});\r\n\t// }\r\n};\r\n\r\nexport const rememberDeathrattles = (\r\n\tfish: BoardEntity,\r\n\tinputDeadEntities: readonly BoardEntity[],\r\n\tcardsData: CardsData,\r\n\tallCards: AllCardsService,\r\n\tsharedState: SharedState,\r\n): void => {\r\n\tconst deadEntities = inputDeadEntities.filter((e) => !isFish(e));\r\n\tif (!deadEntities?.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\t// Some infinite loops going on?\r\n\tif (fish.rememberedDeathrattles?.length > 100) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst debug = deadEntities.some((e) => e.cardId === CardIds.CorruptedBristler_BG32_431);\r\n\r\n\tconst validDeathrattles = deadEntities\r\n\t\t.filter((entity) => allCards.getCard(entity.cardId).mechanics?.includes(GameTag[GameTag.DEATHRATTLE]))\r\n\t\t.filter((e) => !DEATHRATTLES_REQUIRE_MEMORY.includes(e.cardId as CardIds) || e.memory)\r\n\t\t.map((entity) => ({\r\n\t\t\tcardId: entity.cardId,\r\n\t\t\trepeats: 1,\r\n\t\t\ttiming: sharedState.currentEntityId++,\r\n\t\t\tmemory: entity.memory,\r\n\t\t\tscriptDataNum1: entity.scriptDataNum1,\r\n\t\t\tscriptDataNum2: entity.scriptDataNum2,\r\n\t\t}));\r\n\tconst validEnchantments = deadEntities\r\n\t\t.map((entity) => entity.enchantments)\r\n\t\t.reduce((a, b) => a.concat(b), [])\r\n\t\t.flatMap((enchantment) => ({\r\n\t\t\tcardId: enchantment.cardId,\r\n\t\t\trepeats: enchantment.repeats ?? 1,\r\n\t\t\ttiming: sharedState.currentEntityId++,\r\n\t\t}))\r\n\t\t.filter((enchantment) => isValidDeathrattleEnchantment(enchantment.cardId));\r\n\t// Multiple fish\r\n\tconst deadEntityRememberedDeathrattles =\r\n\t\tdeadEntities\r\n\t\t\t.filter((e) => !!e.rememberedDeathrattles?.length)\r\n\t\t\t// If the fish has reborn, it will inherit its own Deathrattles, and we don't want that\r\n\t\t\t.filter((e) => e.entityId !== fish.rebornFromEntityId)\r\n\t\t\t.filter((e) => !DEATHRATTLES_REQUIRE_MEMORY.includes(e.cardId as CardIds) || e.memory)\r\n\t\t\t.flatMap((e) => e.rememberedDeathrattles) ?? [];\r\n\tconst newDeathrattles = [...validDeathrattles, ...validEnchantments, ...deadEntityRememberedDeathrattles];\r\n\r\n\tif (newDeathrattles.length > 0) {\r\n\t\t// Order is important - the DR are triggered in the order d the minions have died\r\n\t\tif (isGolden(fish.cardId, allCards)) {\r\n\t\t\t// https://stackoverflow.com/questions/33305152/how-to-duplicate-elements-in-a-js-array\r\n\t\t\tconst doubleDr = newDeathrattles.reduce((res, current) => res.concat([current, current]), []);\r\n\t\t\tfish.rememberedDeathrattles = [...(fish.rememberedDeathrattles || []), ...doubleDr];\r\n\t\t} else {\r\n\t\t\tfish.rememberedDeathrattles = [...(fish.rememberedDeathrattles || []), ...newDeathrattles];\r\n\t\t}\r\n\r\n\t\tif (newDeathrattles.some((d) => d.cardId?.startsWith(CardIds.Leapfrogger_BG21_000))) {\r\n\t\t\t// Not sure exactly why, but if a leapfrogger dies first, then a manasaber,\r\n\t\t\t// when the fish dies, the manasaber's effect (spawning tokens) is triggered first\r\n\t\t\t// https://replays.firestoneapp.com/?reviewId=521733fb-8ba1-4663-9a87-3da58e8a09c8&turn=21&action=3\r\n\t\t\t// HACK: So I will hardcode a rule for now to put leapfrogger effects last\r\n\t\t\tconst leapfroggerDeathrattles = groupLeapfroggerDeathrattles(fish.rememberedDeathrattles);\r\n\t\t\tfish.rememberedDeathrattles = [\r\n\t\t\t\t...fish.rememberedDeathrattles.filter((d) => !d.cardId?.startsWith(CardIds.Leapfrogger_BG21_000)),\r\n\t\t\t\t...leapfroggerDeathrattles,\r\n\t\t\t];\r\n\t\t}\r\n\t}\r\n\t// console.debug(\r\n\t// \t'remembered',\r\n\t// \tfish.cardId,\r\n\t// \tfish.entityId,\r\n\t// \tfish.rememberedDeathrattles.map((d) => ({\r\n\t// \t\tcardId: d.cardId,\r\n\t// \t\tname: allCards.getCard(d.cardId)?.name,\r\n\t// \t\t// repeats: d.repeats,\r\n\t// \t\t// timing: d.timing,\r\n\t// \t})),\r\n\t// );\r\n};\r\n\r\nconst removeOldMurkEyeAttack = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\t// const murkeyes = boardWithDeadEntity.filter(\r\n\t// \t(entity) => entity.cardId === CardIds.OldMurkEyeLegacy || entity.cardId === CardIds.OldMurkEyeVanilla,\r\n\t// );\r\n\t// const goldenMurkeyes = boardWithDeadEntity.filter((entity) => entity.cardId === CardIds.OldMurkEye);\r\n\t// murkeyes.forEach((entity) => {\r\n\t// \tmodifyStats(entity, null, -1, 0, boardWithDeadEntity, hero, gameState);\r\n\t// });\r\n\t// goldenMurkeyes.forEach((entity) => {\r\n\t// \tmodifyStats(entity, null, -2, 0, boardWithDeadEntity, hero, gameState);\r\n\t// });\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"deathrattle-effects.js","sourceRoot":"","sources":["../../src/simulation/deathrattle-effects.ts"],"names":[],"mappings":";;;AACA,iEAA8E;AAI9E,6EAAkG;AAClG,6DAA+D;AAC/D,6CAAgD;AAEhD,6CAAgE;AAChE,gEAAuE;AACvE,oCAOkB;AAClB,qCAA8C;AAC9C,mDAAiD;AACjD,6DAAqD;AAErD,qEAAwE;AAExE,mCAAsC;AAEtC,MAAM,2BAA2B,GAAG,0BAAwE,CAAC;AAEtG,MAAM,4BAA4B,GAAG,CAC3C,KAAoB,EACpB,SAA0B,EAC1B,UAAuB,EACvB,WAAwB,EACf,EAAE;;IACX,MAAM,SAAS,GACd,CAAC,CAAC,KAAK,CAAC,IAAI,CACX,CAAC,MAAM,EAAE,EAAE,CACV,MAAM,CAAC,MAAM,iBAAsC;QACnD,MAAM,CAAC,MAAM,eAAsC,CACpD,KAAI,MAAA,SAAS,CAAC,OAAO,0CAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAkC,CAAC,CAAA,CAAC;IACjF,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CACjC,CAAC,MAAM,EAAE,EAAE,CACV,MAAM,CAAC,MAAM,sBAA2C;QACxD,MAAM,CAAC,MAAM,iBAAwC,CACtD,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,eAAoC,CAAC,CAAC,MAAM,CAAC;IACjG,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,iBAAsC,CAAC,CAAC,MAAM,CAAC;IACzG,MAAM,mBAAmB,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CACpD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAAiD,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,CACxF,CAAC,MAAM,CAAC;IACT,MAAM,KAAK,GACV,MAAA,MAAA,MAAA,SAAS,CAAC,mBAAmB,0CAAE,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,sBAA2B,CAAC,0CAAE,MAAM,mCAAI,CAAC,CAAC;IAC1G,MAAM,aAAa,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,oBAAwC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrG,MAAM,iBAAiB,GAAG,CAAA,MAAA,UAAU,CAAC,eAAe,0CAAE,QAAQ,WAAsB,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7F,MAAM,UAAU,GACf,iBAAiB;QACjB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,mBAAmB;YACnB,KAAK;YACL,CAAC,GAAG,WAAW;YACf,KAAK;YACL,aAAa,CAAC,CAAC;IACjB,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AApCW,QAAA,4BAA4B,gCAoCvC;AAEK,MAAM,mCAAmC,GAAG,CAClD,mBAAkC,EAClC,uBAAwC,EACxC,UAAyC,EACzC,UAAyB,EACzB,cAA+B,EAC/B,SAAwB,EACjB,EAAE;IAET,MAAM,UAAU,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,6BAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,gBAAgB,GAAI,UAA0B,CAAC,QAAQ,CAAC;IAC7D,UAA0B,CAAC,QAAQ,GAAG,KAAK,CAAC;IAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,OAAO,GAAG,IAAA,mCAA2B,EAAC,UAAU,EAAE,CAAC,CAAC,CAAC;QAC3D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC7B,IAAA,2BAAkB,EACjB,MAAM,EACN,UAAU,EACV,cAAc,EACd,UAAU,EACV,CAAC,EACD,mBAAmB,EACnB,uBAAuB,EACvB,SAAS,CACT,CAAC;SACF;KACD;IACA,UAA0B,CAAC,QAAQ,GAAG,gBAAgB,CAAC;AACzD,CAAC,CAAC;AA5BW,QAAA,mCAAmC,uCA4B9C;AAEK,MAAM,+BAA+B,GAAG,CAC9C,mBAAkC,EAClC,uBAAwC,EACxC,SAA0B,EAC1B,UAAuB,EACvB,YAA2C,EAC3C,SAAwB,EACjB,EAAE;IACT,MAAM,UAAU,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,6BAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QACxF,MAAM,MAAM,GAAgB,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,CAAC,MAAM,EAAE;YACb,IAAA,mBAAW,EAAC,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YAC9F,IAAA,kCAAkB,EAAC,MAAM,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;SACrG;KACD;AACF,CAAC,CAAC;AAjBW,QAAA,+BAA+B,mCAiB1C;AAEK,MAAM,8BAA8B,GAAG,CAC7C,mBAAkC,EAClC,uBAAwC,EACxC,UAAuB,EACvB,YAA2C,EAC3C,SAAwB,EACjB,EAAE;IACT,MAAM,UAAU,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,6BAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,MAAM,GAAgB,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QACpG,IAAI,CAAC,CAAC,MAAM,EAAE;YACb,IAAA,mBAAW,EACV,MAAM,EACN,YAAY,EACZ,MAAM,CAAC,MAAM,EACb,CAAC,EACD,mBAAmB,EACnB,uBAAuB,EACvB,SAAS,CACT,CAAC;SACF;KACD;AACF,CAAC,CAAC;AAtBW,QAAA,8BAA8B,kCAsBzC;AAEK,MAAM,+BAA+B,GAAG,CAC9C,mBAAkC,EAClC,UAAuB,EACvB,YAA2C,EAC3C,SAAwB,EACjB,EAAE;IACT,MAAM,UAAU,GAAG,CAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,MAAM,6BAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,yBAAyB,GAAkB,IAAA,mCAA2B,EAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;QACrG,yBAAyB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YAC5C,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;gBACxB,MAAM,sBAAiD;gBACvD,cAAc,EAAE,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ;gBACpC,MAAM,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe,EAAE;aAC/C,CAAC,CAAC;YACH,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAChG,CAAC,CAAC,CAAC;KACH;AACF,CAAC,CAAC;AAlBW,QAAA,+BAA+B,mCAkB1C;AAEK,MAAM,sBAAsB,GAAG,CACrC,mBAAkC,EAClC,uBAAwC,EACxC,UAAuB,EACvB,SAAkB,EAClB,SAAwB,EACxB,UAAkB,EACX,EAAE;;IACT,UAAU,GAAG,MAAA,UAAU,aAAV,UAAU,cAAV,UAAU,GAAI,UAAU,CAAC,kBAAkB,mCAAI,CAAC,CAAC;IAE9D,MAAM,MAAM,GAAG,IAAA,wBAAgB,EAC9B,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,UAAU,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAChC,UAAU,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAChC,qBAAI,CAAC,KAAK,EACV,KAAK,EACL,SAAS,CACT,CAAC;IACF,IAAI,MAAM,EAAE;QACX,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;YACxB,MAAM,EAAE,SAAS;gBAChB,CAAC;gBACD,CAAC,YAAqD;YACvD,cAAc,EAAE,UAAU,CAAC,QAAQ;YACnC,OAAO,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACxC,MAAM,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe,EAAE;SAC/C,CAAC,CAAC;KACH;AACF,CAAC,CAAC;AA9BW,QAAA,sBAAsB,0BA8BjC;AAEK,MAAM,wCAAwC,GAAG,CACvD,mBAAkC,EAClC,uBAAwC,EACxC,UAAuB,EACvB,SAAkB,EAClB,SAAwB,EACxB,UAAU,GAAG,CAAC,EACP,EAAE;AAyBV,CAAC,CAAC;AAhCW,QAAA,wCAAwC,4CAgCnD;AAIK,MAAM,+BAA+B,GAAG,CAC9C,KAAoB,EACpB,IAAqB,EACrB,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACjB,EAAE;IACT,uCAAuC,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAGxF,CAAC,CAAC;AAVW,QAAA,+BAA+B,mCAU1C;AAEF,MAAM,uCAAuC,GAAG,CAC/C,KAAoB,EACpB,IAAqB,EACrB,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACjB,EAAE;IACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE;YACpD,MAAM,gBAAgB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,oBAAoB,CAAC;YACrD,IAAI,CAAC,MAAM,EAAE;gBACZ,OAAO;aACP;YAGD,IAAI,MAAM,CAAC,QAAQ,KAAK,gBAAgB,CAAC,QAAQ,EAAE;gBAClD,KAAK,MAAM,SAAS,IAAI,SAAS,CAAC,UAAU,EAAE;oBAG7C,IAAI,SAAS,CAAC,MAAM,qBAAiC,IAAI,CAAC,IAAA,cAAM,EAAC,MAAM,CAAC,EAAE;wBACzE,IAAA,mBAAW,EAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;qBACvE;iBACD;gBAGD,UAAU;qBACR,MAAM,CACN,CAAC,CAAC,EAAE,EAAE,CACL,CAAC,CAAC,MAAM,0BAAkD;oBAC1D,CAAC,CAAC,MAAM,4BAAoD,CAC7D;qBAIA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC;qBAChD,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;oBACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,4BAAoD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzF,IAAA,mBAAW,EAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;gBACtE,CAAC,CAAC,CAAC;aACJ;SACD;KACD;AACF,CAAC,CAAC;AAEK,MAAM,4BAA4B,GAAG,CAC3C,UAAuB,EACvB,wBAAgC,EAChC,mBAAkC,EAClC,uBAAwC,EACxC,UAAyB,EACzB,cAA+B,EAC/B,SAAwB,EACjB,EAAE;AASV,CAAC,CAAC;AAjBW,QAAA,4BAA4B,gCAiBvC;AAEK,MAAM,0BAA0B,GAAG,CACzC,UAAuB,EACvB,wBAAgC,EAChC,mBAAkC,EAClC,uBAAwC,EACxC,UAAyB,EACzB,cAA+B,EAC/B,SAAwB,EACjB,EAAE;IACT,IAAI,IAAA,uBAAe,EAAC,UAAU,EAAE,uBAAuB,EAAE,qBAAI,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;QAC9G,IAAA,8BAAsB,EAAC,mBAAmB,EAAE,uBAAuB,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;KAC5G;AACF,CAAC,CAAC;AAZW,QAAA,0BAA0B,8BAYrC;AAEK,MAAM,6BAA6B,GAAG,CAC5C,UAAuB,EACvB,wBAAgC,EAChC,mBAAkC,EAClC,uBAAwC,EACxC,UAAyB,EACzB,cAA+B,EAC/B,SAAwB,EACjB,EAAE;;IAET,IAAI,IAAA,uBAAe,EAAC,UAAU,EAAE,uBAAuB,EAAE,qBAAI,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;QAC9G,0BAA0B,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;KACpF;IACD,IAAI,IAAA,uBAAe,EAAC,UAAU,EAAE,uBAAuB,EAAE,qBAAI,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;QAC7G,kBAAkB,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;KAC5E;IACD,IAAI,IAAA,uBAAe,EAAC,UAAU,EAAE,uBAAuB,EAAE,qBAAI,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;QAC/G,sBAAsB,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;QAChF,sBAAsB,CAAC,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;KAC9D;IACD,IAAI,IAAA,uBAAe,EAAC,UAAU,EAAE,uBAAuB,EAAE,qBAAI,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;QAClH,2BAA2B,CAAC,UAAU,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;KACjG;IAED,IAAI,UAAU,CAAC,KAAK,EAAE;QACrB,gCAAgC,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;QAC1F,2BAA2B,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,SAAS,CAAC,CAAC;KAC/G;IAED,IACC,UAAU,CAAC,MAAM,eAAmC;QACpD,UAAU,CAAC,MAAM,iBAAqC,EACrD;QACD,wBAAwB,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;KAClF;IAGD,mBAAmB;SACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,eAAe,0CAAE,QAAQ,eAA4C,CAAA,EAAA,CAAC;SACtF,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACd,IAAA,mBAAW,EAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEJ,uBAAuB,CAAC,mBAAmB,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;IAGjF,IACC,UAAU,CAAC,MAAM,GAAG,CAAC;QACrB,SAAS,CAAC,WAAW,CAAC,uBAAuB,IAAI,IAAI;QACrD,SAAS,CAAC,WAAW,CAAC,uBAAuB,MAAK,MAAA,UAAU,CAAC,oBAAoB,0CAAE,QAAQ,CAAA,EAC1F;QA+ED,IAAI,UAAU,CAAC,oBAAoB,CAAC,MAAM,cAAqC,EAAE;YAChF,MAAM,WAAW,GAAG,IAAA,kCAAa,cAEhC,CAAC,EACD,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,SAAS,EACT,CAAC,UAAU,CAAC,QAAQ,EACpB,KAAK,CACL,CAAC;YACF,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,wBAAwB,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC;SA4DnF;KACD;AACF,CAAC,CAAC;AA3MW,QAAA,6BAA6B,iCA2MxC;AAGK,MAAM,sBAAsB,GAAG,CACrC,MAAqB,EACrB,UAA2B,EAC3B,MAAqB,EACrB,UAA2B,EAC3B,YAAyB,EACzB,WAAmB,EACnB,SAAwB,EACjB,EAAE;IACT,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/C,OAAO;KACP;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACvC,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;KAC5G;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACvC,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;KAC5G;AACF,CAAC,CAAC;AAlBW,QAAA,sBAAsB,0BAkBjC;AAEK,MAAM,sBAAsB,GAAG,CACrC,iBAAgC,EAChC,qBAAsC,EACtC,aAA4B,EAC5B,iBAAkC,EAClC,SAAwB,EACjB,EAAE;IACT,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;QACjE,OAAO;KAEP;IACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,cAAgC,CAAC,CAAC;IACrG,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;QAC/B,MAAM,MAAM,GAAG,IAAA,wCAAgC,EAAC,aAAa,CAAC,CAAC;QAC/D,SAAS,CAAC,SAAS,CAAC,mBAAmB,CACtC,OAAO,EACP,MAAM,EACN,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,CACjB,CAAC;QACF,IAAA,2BAAkB,EACjB,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,CAAC,EACD,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,CACT,CAAC;KACF;IACD,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,sBAAwC,CAAC,CAAC;IACnH,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,IAAA,wCAAgC,EAAC,aAAa,CAAC,CAAC;YAC/D,SAAS,CAAC,SAAS,CAAC,mBAAmB,CACtC,OAAO,EACP,MAAM,EACN,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,CACjB,CAAC;YACF,IAAA,2BAAkB,EACjB,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,CAAC,EACD,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,CACT,CAAC;SACF;KACD;AAWF,CAAC,CAAC;AAjEW,QAAA,sBAAsB,0BAiEjC;AAEF,MAAM,0BAA0B,GAAG,CAClC,KAAoB,EACpB,uBAAwC,EACxC,SAAwB,EACjB,EAAE;IAET,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,iBAA6C,EAAE;YACjE,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;YAC7E,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;SAC/E;aAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,sBAAkD,EAAE;YAC7E,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,SAAS,CAAC,CAAC;YAC7E,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;SAC/E;KACD;AACF,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,KAAoB,EAAE,IAAqB,EAAE,SAAwB,EAAQ,EAAE;IAChH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IACC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,eAAmC;YAClD,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,iBAAqC,EACnD;YACD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,iBAAqC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAChF,IAAA,mBAAW,EACV,KAAK,CAAC,CAAC,CAAC,EACR,IAAI,EACJ,UAAU,GAAG,sCAAmB,EAChC,UAAU,GAAG,sCAAmB,EAChC,KAAK,EACL,IAAI,EACJ,SAAS,CACT,CAAC;YACF,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;SAC/E;KACD;AACF,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG,CAAC,KAAoB,EAAE,IAAqB,EAAE,SAAwB,EAAQ,EAAE;IAC/G,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,eAAkC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,iBAAoC,EAAE;YAC7G,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,iBAAoC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/E,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;YACvE,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;SAC/E;KACD;AACF,CAAC,CAAC;AAEF,MAAM,gCAAgC,GAAG,CACxC,KAAoB,EACpB,iBAAkC,EAClC,SAAwB,EACjB,EAAE;IACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IACC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,eAA2C;YAC1D,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,iBAA6C,EAC3D;YACD,MAAM,UAAU,GAAG,KAAK,CAAC,aAAyC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAkB,CAAC;YAClG,IAAA,8BAAc,EAAC,iBAAiB,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YAChE,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC;SAC5F;KACD;AACF,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,CACnC,UAAuB,EACvB,KAAoB,EACpB,IAAqB,EACrB,SAAwB,EACjB,EAAE;IACT,KAAK;SACH,MAAM,CACN,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAsC,IAAI,CAAC,CAAC,MAAM,iBAAwC,CACzG;SACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAC;SACtC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QACnB,IAAA,mBAAW,EAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QAC9F,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC3B,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,KAAoB,EAAE,IAAqB,EAAE,SAAwB,EAAQ,EAAE;IAC1G,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,cAA4B,EAAE;YAChD,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;SAG9D;KACD;AACF,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,CACnC,KAAoB,EACpB,IAAqB,EACrB,wBAAgC,EAChC,SAAwB,EACjB,EAAE;AAWV,CAAC,CAAC;AAEK,MAAM,oBAAoB,GAAG,CACnC,IAAiB,EACjB,iBAAyC,EACzC,SAAoB,EACpB,QAAyB,EACzB,WAAwB,EACjB,EAAE;;IACT,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAA,cAAM,EAAC,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,CAAC,CAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,CAAA,EAAE;QAC1B,OAAO;KACP;IAGD,IAAI,CAAA,MAAA,IAAI,CAAC,sBAAsB,0CAAE,MAAM,IAAG,GAAG,EAAE;QAC9C,OAAO;KACP;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAuC,CAAC,CAAC;IAExF,MAAM,iBAAiB,GAAG,YAAY;SACpC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,WAAC,OAAA,MAAA,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,0CAAE,QAAQ,CAAC,wBAAO,CAAC,wBAAO,CAAC,WAAW,CAAC,CAAC,CAAA,EAAA,CAAC;SACrG,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;SACrF,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,WAAW,CAAC,eAAe,EAAE;QACrC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;KACrC,CAAC,CAAC,CAAC;IACL,MAAM,iBAAiB,GAAG,YAAY;SACpC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC;SACpC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;SACjC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;;QAAC,OAAA,CAAC;YAC1B,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,OAAO,EAAE,MAAA,WAAW,CAAC,OAAO,mCAAI,CAAC;YACjC,MAAM,EAAE,WAAW,CAAC,eAAe,EAAE;SACrC,CAAC,CAAA;KAAA,CAAC;SACF,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAA,mDAA6B,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAE7E,MAAM,gCAAgC,GACrC,MAAA,YAAY;SACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,CAAC,CAAC,CAAA,MAAA,CAAC,CAAC,sBAAsB,0CAAE,MAAM,CAAA,CAAA,EAAA,CAAC;SAEjD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,kBAAkB,CAAC;SACrD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAiB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;SACrF,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,mCAAI,EAAE,CAAC;IAClD,MAAM,eAAe,GAAG,CAAC,GAAG,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,GAAG,gCAAgC,CAAC,CAAC;IAE1G,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;QAG/B,IAAI,IAAA,cAAM,EAAC,IAAI,CAAC,IAAI,IAAA,gBAAQ,EAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;YAEpD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9F,IAAI,CAAC,sBAAsB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,IAAI,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC;SACpF;aAAM;YACN,IAAI,CAAC,sBAAsB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,IAAI,EAAE,CAAC,EAAE,GAAG,eAAe,CAAC,CAAC;SAC3F;QAED,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,MAAM,0CAAE,UAAU,YAA8B,CAAA,EAAA,CAAC,EAAE;YAKpF,MAAM,uBAAuB,GAAG,IAAA,qDAA4B,EAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YAC1F,IAAI,CAAC,sBAAsB,GAAG;gBAC7B,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,CAAC,CAAA,MAAA,CAAC,CAAC,MAAM,0CAAE,UAAU,YAA8B,CAAA,CAAA,EAAA,CAAC;gBACjG,GAAG,uBAAuB;aAC1B,CAAC;SACF;KACD;AAYF,CAAC,CAAC;AAnFW,QAAA,oBAAoB,wBAmF/B;AAEF,MAAM,sBAAsB,GAAG,CAC9B,mBAAkC,EAClC,IAAqB,EACrB,SAAwB,EACvB,EAAE;AAWJ,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\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 { CardsData } from '../cards/cards-data';\r\nimport { eternalKnightAttack, eternalKnightHealth } from '../cards/impl/trinket/eternal-portrait';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { updateTaunt } from '../keywords/taunt';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickMultipleRandomDifferent } from '../services/utils';\r\nimport { isValidDeathrattleEnchantment } from '../simulate-bgs-battle';\r\nimport {\r\n\tgetRandomMinionWithHighestHealth,\r\n\tgrantRandomStats,\r\n\thasCorrectTribe,\r\n\tisDead,\r\n\tisFish,\r\n\tisGolden,\r\n} from '../utils';\r\nimport { dealDamageToMinion } from './attack';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { groupLeapfroggerDeathrattles } from './remembered-deathrattle';\r\nimport { SharedState } from './shared-state';\r\nimport { modifyStats } from './stats';\r\n\r\nconst DEATHRATTLES_REQUIRE_MEMORY = [CardIds.StitchedSalvager_BG31_999, CardIds.StitchedSalvager_BG31_999_G];\r\n\r\nexport const computeDeathrattleMultiplier = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tsharedState: SharedState,\r\n): number => {\r\n\tconst rivendare =\r\n\t\t!!board.find(\r\n\t\t\t(entity) =>\r\n\t\t\t\tentity.cardId === CardIds.BaronRivendare_BG_FP1_031 ||\r\n\t\t\t\tentity.cardId === CardIds.MoiraBronzebeard_BG27_518,\r\n\t\t) || boardHero.secrets?.some((e) => e.cardId === CardIds.TitusTribute_BG28_843);\r\n\tconst goldenRivendare = board.find(\r\n\t\t(entity) =>\r\n\t\t\tentity.cardId === CardIds.BaronRivendare_TB_BaconUps_055 ||\r\n\t\t\tentity.cardId === CardIds.MoiraBronzebeard_BG27_518_G,\r\n\t);\r\n\tconst titus = board.filter((entity) => entity.cardId === CardIds.TitusRivendare_BG25_354).length;\r\n\tconst goldenTitus = board.filter((entity) => entity.cardId === CardIds.TitusRivendare_BG25_354_G).length;\r\n\tconst deathlyPhylacteries = boardHero.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.DeathlyPhylactery_BG30_MagicItem_700 && t.scriptDataNum1 > 0,\r\n\t).length;\r\n\tconst tombs =\r\n\t\tboardHero.questRewardEntities?.filter((entity) => entity.cardId === CardIds.TurbulentTombs)?.length ?? 0;\r\n\tconst echoesOfArgus = sharedState.anomalies.includes(CardIds.EchoesOfArgus_BG27_Anomaly_802) ? 1 : 0;\r\n\tconst scourgeMultiplier = deadEntity.additionalCards?.includes(CardIds.ScourgeTroll) ? 2 : 1;\r\n\r\n\tconst multiplier =\r\n\t\tscourgeMultiplier *\r\n\t\t((goldenRivendare ? 3 : rivendare ? 2 : 1) +\r\n\t\t\tdeathlyPhylacteries +\r\n\t\t\ttitus +\r\n\t\t\t2 * goldenTitus +\r\n\t\t\ttombs +\r\n\t\t\techoesOfArgus);\r\n\treturn multiplier;\r\n};\r\n\r\nexport const applyLightningInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity | BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// Because the golden version doubles all the remembered effects\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tconst previousVenomous = (deadEntity as BoardEntity).venomous;\r\n\t(deadEntity as BoardEntity).venomous = false;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst targets = pickMultipleRandomDifferent(otherBoard, 5);\r\n\t\tfor (const target of targets) {\r\n\t\t\tdealDamageToMinion(\r\n\t\t\t\ttarget,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherBoardHero,\r\n\t\t\t\tdeadEntity,\r\n\t\t\t\t1,\r\n\t\t\t\tboardWithDeadEntity,\r\n\t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\t(deadEntity as BoardEntity).venomous = previousVenomous;\r\n};\r\n\r\nexport const applyWaterInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity, // Can be null when trinket is used\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst validBoard = boardWithDeadEntity.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\t\tconst target: BoardEntity = validBoard[validBoard.length - 1];\r\n\t\tif (!!target) {\r\n\t\t\tupdateTaunt(target, true, boardWithDeadEntity, boardWithDeadEntityHero, otherHero, gameState);\r\n\t\t\tupdateDivineShield(target, boardWithDeadEntity, boardWithDeadEntityHero, otherHero, true, gameState);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const applyFireInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst target: BoardEntity = boardWithDeadEntity.filter((e) => e.health > 0 && !e.definitelyDead)[0];\r\n\t\tif (!!target) {\r\n\t\t\tmodifyStats(\r\n\t\t\t\ttarget,\r\n\t\t\t\tsourceEntity,\r\n\t\t\t\ttarget.attack,\r\n\t\t\t\t0,\r\n\t\t\t\tboardWithDeadEntity,\r\n\t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const applyEarthInvocationEnchantment = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tdeadEntity: BoardEntity,\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst multiplier = deadEntity?.cardId === CardIds.SpiritRaptor_BG22_HERO_001_Buddy_G ? 2 : 1;\r\n\tfor (let i = 0; i < multiplier; i++) {\r\n\t\tconst minionsGrantedDeathrattle: BoardEntity[] = pickMultipleRandomDifferent(boardWithDeadEntity, 4);\r\n\t\tminionsGrantedDeathrattle.forEach((minion) => {\r\n\t\t\tminion.enchantments.push({\r\n\t\t\t\tcardId: CardIds.EarthInvocation_ElementEarthEnchantment,\r\n\t\t\t\toriginEntityId: deadEntity?.entityId,\r\n\t\t\t\ttiming: gameState.sharedState.currentEntityId++,\r\n\t\t\t});\r\n\t\t\tgameState.spectator.registerPowerTarget(sourceEntity, minion, boardWithDeadEntity, null, null);\r\n\t\t});\r\n\t}\r\n};\r\n\r\nexport const applyLeapFroggerEffect = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tisPremium: boolean,\r\n\tgameState: FullGameState,\r\n\tmultiplier: number,\r\n): void => {\r\n\tmultiplier = multiplier ?? deadEntity.deathrattleRepeats ?? 1;\r\n\t// console.debug('applying leapfrogger effect', deadEntity.entityId, multiplier);\r\n\tconst buffed = grantRandomStats(\r\n\t\tdeadEntity,\r\n\t\tboardWithDeadEntity,\r\n\t\tboardWithDeadEntityHero,\r\n\t\tmultiplier * (isPremium ? 2 : 1),\r\n\t\tmultiplier * (isPremium ? 2 : 1),\r\n\t\tRace.BEAST,\r\n\t\tfalse,\r\n\t\tgameState,\r\n\t);\r\n\tif (buffed) {\r\n\t\tbuffed.enchantments.push({\r\n\t\t\tcardId: isPremium\r\n\t\t\t\t? CardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge\r\n\t\t\t\t: CardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\t\t\toriginEntityId: deadEntity.entityId,\r\n\t\t\trepeats: multiplier > 1 ? multiplier : 1,\r\n\t\t\ttiming: gameState.sharedState.currentEntityId++,\r\n\t\t});\r\n\t}\r\n};\r\n\r\nexport const applyRecurringNightmareDeathrattleEffect = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tdeadEntity: BoardEntity,\r\n\tisPremium: boolean,\r\n\tgameState: FullGameState,\r\n\tmultiplier = 1,\r\n): void => {\r\n\t// multiplier = multiplier || 1;\r\n\t// const target = pickRandom(\r\n\t// \tboardWithDeadEntity\r\n\t// \t\t.filter((e) =>\r\n\t// \t\t\thasCorrectTribe(e, boardWithDeadEntityHero, Race.UNDEAD, gameState.anomalies, gameState.allCards),\r\n\t// \t\t)\r\n\t// \t\t.filter(\r\n\t// \t\t\t(e) =>\r\n\t// \t\t\t\te.cardId !== CardIds.RecurringNightmare_BG26_055 &&\r\n\t// \t\t\t\te.cardId !== CardIds.RecurringNightmare_BG26_055_G,\r\n\t// \t\t),\r\n\t// );\r\n\t// if (target) {\r\n\t// \ttarget.enchantments = target.enchantments ?? [];\r\n\t// \ttarget.enchantments.push({\r\n\t// \t\tcardId: isPremium\r\n\t// \t\t\t? CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge\r\n\t// \t\t\t: CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\t// \t\toriginEntityId: deadEntity.entityId,\r\n\t// \t\trepeats: multiplier > 1 ? multiplier : 1,\r\n\t// \t\ttiming: gameState.sharedState.currentEntityId++,\r\n\t// \t});\r\n\t// \tgameState.spectator.registerPowerTarget(deadEntity, target, boardWithDeadEntity, null, null);\r\n\t// }\r\n};\r\n\r\n// Some minions like Icesnarl can revive themselves when killing a minion, so it needs to be handled before\r\n// we actually make the minion die\r\nexport const handleWheneverMinionsKillEffect = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\thandleWheneverMinionsKillEffectForBoard(board, hero, otherBoard, otherHero, gameState);\r\n\t// It's called once for each board already, so don't duplicate it here\r\n\t// handleWheneverMinionsKillEffectForBoard(otherBoard, otherHero, board, hero, gameState);\r\n};\r\n\r\nconst handleWheneverMinionsKillEffectForBoard = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\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\tconst futureDeadEntity = board[i];\r\n\t\t\tconst killer = futureDeadEntity.lastAffectedByEntity;\r\n\t\t\tif (!killer) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Killed an enemy minion\r\n\t\t\tif (killer.friendly !== futureDeadEntity.friendly) {\r\n\t\t\t\tfor (const heroPower of otherHero.heroPowers) {\r\n\t\t\t\t\t// Can't be used to resurrect a dead minion\r\n\t\t\t\t\t// https://replays.firestoneapp.com/?reviewId=d1fffee8-0bc3-40f5-9a59-85eef8367095&turn=11&action=4\r\n\t\t\t\t\tif (heroPower.cardId === CardIds.Rokara_GloryOfCombat && !isDead(killer)) {\r\n\t\t\t\t\t\tmodifyStats(killer, otherHero, 1, 0, otherBoard, otherHero, gameState);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Icesnarl the Mighty\r\n\t\t\t\totherBoard\r\n\t\t\t\t\t.filter(\r\n\t\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t\te.cardId === CardIds.IcesnarlTheMighty_BG20_HERO_100_Buddy ||\r\n\t\t\t\t\t\t\te.cardId === CardIds.IcesnarlTheMighty_BG20_HERO_100_Buddy_G,\r\n\t\t\t\t\t)\r\n\t\t\t\t\t// Can't be revived\r\n\t\t\t\t\t// 33.6 https://replays.firestoneapp.com/?reviewId=608ddffb-6c04-4def-a8de-fd39228f4de4&turn=11&action=4\r\n\t\t\t\t\t// Maybe should move to an \"after kill\" phase, where dead minions are already dead?\r\n\t\t\t\t\t.filter((e) => e.health > 0 && !e.definitelyDead)\r\n\t\t\t\t\t.forEach((icesnarl) => {\r\n\t\t\t\t\t\tconst mult = icesnarl.cardId === CardIds.IcesnarlTheMighty_BG20_HERO_100_Buddy_G ? 2 : 1;\r\n\t\t\t\t\t\tmodifyStats(icesnarl, icesnarl, 0, 3 * mult, board, hero, gameState);\r\n\t\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const handleAfterMinionKillsEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// Moved to \"whenever kills\", as these can revive the minion that kills\r\n\t// const killer = deadEntity.lastAffectedByEntity;\r\n\t// if (!killer) {\r\n\t// \treturn;\r\n\t// }\r\n\t// // Killed an enemy minion\r\n\t// if (killer.friendly !== deadEntity.friendly) {\r\n\t// }\r\n};\r\n\r\nexport const applyAfterMinionDiesEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.DEMON, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplySoulJugglerEffect(boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState);\r\n\t}\r\n};\r\n\r\nexport const applyWheneverMinionDiesEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// console.log('applying minion death effect', stringifySimpleCard(deadEntity, allCards));\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.BEAST, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplyScavengingHyenaEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.MECH, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplyJunkbotEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.MURLOC, gameState.anomalies, gameState.allCards)) {\r\n\t\tremoveOldMurkEyeAttack(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t\tremoveOldMurkEyeAttack(otherBoard, otherBoardHero, gameState);\r\n\t}\r\n\tif (hasCorrectTribe(deadEntity, boardWithDeadEntityHero, Race.ELEMENTAL, gameState.anomalies, gameState.allCards)) {\r\n\t\tapplyMossOfTheSchlossEffect(deadEntity, boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\r\n\tif (deadEntity.taunt) {\r\n\t\tapplyBristlemaneScrapsmithEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t\tapplyQirajiHarbringerEffect(boardWithDeadEntity, boardWithDeadEntityHero, deadEntityIndexFromRight, gameState);\r\n\t}\r\n\r\n\tif (\r\n\t\tdeadEntity.cardId === CardIds.EternalKnight_BG25_008 ||\r\n\t\tdeadEntity.cardId === CardIds.EternalKnight_BG25_008_G\r\n\t) {\r\n\t\tapplyEternalKnightEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t}\r\n\r\n\t// Putricide-only\r\n\tboardWithDeadEntity\r\n\t\t.filter((e) => e.additionalCards?.includes(CardIds.FlesheatingGhoulLegacy_BG26_tt_004))\r\n\t\t.forEach((e) => {\r\n\t\t\tmodifyStats(e, null, 1, 0, boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\t\t});\r\n\r\n\tapplyRotHideGnollEffect(boardWithDeadEntity, boardWithDeadEntityHero, gameState);\r\n\r\n\t// Overkill\r\n\tif (\r\n\t\tdeadEntity.health < 0 &&\r\n\t\tgameState.sharedState.currentAttackerEntityId != null &&\r\n\t\tgameState.sharedState.currentAttackerEntityId === deadEntity.lastAffectedByEntity?.entityId\r\n\t) {\r\n\t\t// if (deadEntity.lastAffectedByEntity.cardId === CardIds.HeraldOfFlame_BGS_032) {\r\n\t\t// \tconst targets = boardWithDeadEntity.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\t\t// \tif (targets.length > 0) {\r\n\t\t// \t\tconst target = targets[0];\r\n\t\t// \t\tdealDamageToMinion(\r\n\t\t// \t\t\ttarget,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\t3,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tgameState,\r\n\t\t// \t\t);\r\n\t\t// \t}\r\n\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.HeraldOfFlame_TB_BaconUps_103) {\r\n\t\t// \tconst targets = boardWithDeadEntity.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\t\t// \tif (targets.length > 0) {\r\n\t\t// \t\tconst target = targets[0];\r\n\t\t// \t\tdealDamageToMinion(\r\n\t\t// \t\t\ttarget,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\t6,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tgameState,\r\n\t\t// \t\t);\r\n\t\t// \t}\r\n\t\t// }\r\n\t\t// else if (deadEntity.lastAffectedByEntity.cardId === CardIds.WildfireElemental && deadEntity.lastAffectedByEntity.attacking) {\r\n\t\t// \t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.WildfireElemental) {\r\n\t\t// \t// console.log('applying WildfireElemental effect', stringifySimple(boardWithDeadEntity, allCards));\r\n\t\t// \tconst excessDamage = -deadEntity.health;\r\n\t\t// \t// Prevent propagation of the effect\r\n\t\t// \tdeadEntity.lastAffectedByEntity.attacking = false;\r\n\t\t// \tconst neighbours = getNeighbours(boardWithDeadEntity, null, boardWithDeadEntity.length - deadEntityIndexFromRight);\r\n\t\t// \t// console.log('neighbours', stringifySimple(neighbours, allCards));\r\n\t\t// \tif (neighbours.length > 0) {\r\n\t\t// \t\tconst randomTarget = neighbours[Math.floor(Math.random() * neighbours.length)];\r\n\t\t// \t\tdealDamageToEnemy(\r\n\t\t// \t\t\trandomTarget,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\texcessDamage,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tallCards,\r\n\t\t// \t\t\tcardsData,\r\n\t\t// \t\t\tsharedState,\r\n\t\t// \t\t\tspectator,\r\n\t\t// \t\t);\r\n\t\t// \t}\r\n\t\t// } else if (\r\n\t\t// \tdeadEntity.lastAffectedByEntity.cardId === CardIds.WildfireElementalBattlegrounds &&\r\n\t\t// \tdeadEntity.lastAffectedByEntity.attacking\r\n\t\t// ) {\r\n\t\t// \tconst excessDamage = -deadEntity.health;\r\n\t\t// \tdeadEntity.lastAffectedByEntity.attacking = false;\r\n\t\t// \tconst neighbours = getNeighbours(boardWithDeadEntity, null, boardWithDeadEntity.length - deadEntityIndexFromRight);\r\n\t\t// \tneighbours.forEach((neighbour) =>\r\n\t\t// \t\tdealDamageToEnemy(\r\n\t\t// \t\t\tneighbour,\r\n\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t// \t\t\texcessDamage,\r\n\t\t// \t\t\totherBoard,\r\n\t\t// \t\t\totherBoardHero,\r\n\t\t// \t\t\tallCards,\r\n\t\t// \t\t\tcardsData,\r\n\t\t// \t\t\tsharedState,\r\n\t\t// \t\t\tspectator,\r\n\t\t// \t\t),\r\n\t\t// \t);\r\n\t\t// }\r\n\t\tif (deadEntity.lastAffectedByEntity.cardId === CardIds.IronhideDirehorn_TRL_232) {\r\n\t\t\tconst newEntities = spawnEntities(\r\n\t\t\t\tCardIds.IronhideDirehorn_IronhideRuntToken_TRL_232t,\r\n\t\t\t\t1,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherBoardHero,\r\n\t\t\t\tboardWithDeadEntity,\r\n\t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\t!deadEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t);\r\n\t\t\totherBoard.splice(otherBoard.length - deadEntityIndexFromRight, 0, ...newEntities);\r\n\t\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.IronhideDirehorn_TB_BaconUps_051) {\r\n\t\t\t// \tconst newEntities = spawnEntities(\r\n\t\t\t// \t\tCardIds.IronhideDirehorn_IronhideRuntToken_TB_BaconUps_051t,\r\n\t\t\t// \t\t1,\r\n\t\t\t// \t\totherBoard,\r\n\t\t\t// \t\totherBoardHero,\r\n\t\t\t// \t\tboardWithDeadEntity,\r\n\t\t\t// \t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\tgameState,\r\n\t\t\t// \t\t!deadEntity.friendly,\r\n\t\t\t// \t\tfalse,\r\n\t\t\t// \t);\r\n\t\t\t// \totherBoard.splice(otherBoard.length - deadEntityIndexFromRight, 0, ...newEntities);\r\n\t\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.SeabreakerGoliath_BGS_080) {\r\n\t\t\t// \tconst otherPirates = otherBoard\r\n\t\t\t// \t\t.filter((entity) =>\r\n\t\t\t// \t\t\thasCorrectTribe(\r\n\t\t\t// \t\t\t\tentity,\r\n\t\t\t// \t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\t\tRace.PIRATE,\r\n\t\t\t// \t\t\t\tgameState.anomalies,\r\n\t\t\t// \t\t\t\tgameState.allCards,\r\n\t\t\t// \t\t\t),\r\n\t\t\t// \t\t)\r\n\t\t\t// \t\t.filter((entity) => entity.entityId !== deadEntity.lastAffectedByEntity.entityId);\r\n\t\t\t// \totherPirates.forEach((pirate) => {\r\n\t\t\t// \t\tmodifyStats(\r\n\t\t\t// \t\t\tpirate,\r\n\t\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t\t// \t\t\t2,\r\n\t\t\t// \t\t\t2,\r\n\t\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\tgameState,\r\n\t\t\t// \t\t);\r\n\t\t\t// \t});\r\n\t\t\t// } else if (deadEntity.lastAffectedByEntity.cardId === CardIds.SeabreakerGoliath_TB_BaconUps_142) {\r\n\t\t\t// \tconst otherPirates = otherBoard\r\n\t\t\t// \t\t.filter((entity) =>\r\n\t\t\t// \t\t\thasCorrectTribe(\r\n\t\t\t// \t\t\t\tentity,\r\n\t\t\t// \t\t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\t\tRace.PIRATE,\r\n\t\t\t// \t\t\t\tgameState.anomalies,\r\n\t\t\t// \t\t\t\tgameState.allCards,\r\n\t\t\t// \t\t\t),\r\n\t\t\t// \t\t)\r\n\t\t\t// \t\t.filter((entity) => entity.entityId !== deadEntity.lastAffectedByEntity.entityId);\r\n\t\t\t// \totherPirates.forEach((pirate) => {\r\n\t\t\t// \t\tmodifyStats(\r\n\t\t\t// \t\t\tpirate,\r\n\t\t\t// \t\t\tdeadEntity.lastAffectedByEntity,\r\n\t\t\t// \t\t\t4,\r\n\t\t\t// \t\t\t4,\r\n\t\t\t// \t\t\tboardWithDeadEntity,\r\n\t\t\t// \t\t\tboardWithDeadEntityHero,\r\n\t\t\t// \t\t\tgameState,\r\n\t\t\t// \t\t);\r\n\t\t\t// \t});\r\n\t\t}\r\n\t}\r\n};\r\n\r\n/** @deprecated */\r\nexport const dealDamageToAllMinions = (\r\n\tboard1: BoardEntity[],\r\n\tboard1Hero: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tboard2Hero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity,\r\n\tdamageDealt: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (board1.length === 0 && board2.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\tfor (let i = 0; i < board1.length; i++) {\r\n\t\tdealDamageToMinion(board1[i], board1, board1Hero, damageSource, damageDealt, board2, board2Hero, gameState);\r\n\t}\r\n\tfor (let i = 0; i < board2.length; i++) {\r\n\t\tdealDamageToMinion(board2[i], board2, board2Hero, damageSource, damageDealt, board1, board1Hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const applySoulJugglerEffect = (\r\n\tboardWithJugglers: BoardEntity[],\r\n\tboardWithJugglersHero: BgsPlayerEntity,\r\n\tboardToAttack: BoardEntity[],\r\n\tboardToAttackHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (boardWithJugglers.length === 0 && boardToAttack.length === 0) {\r\n\t\treturn;\r\n\t\t// return [boardWithJugglers, boardToAttack];\r\n\t}\r\n\tconst jugglers = boardWithJugglers.filter((entity) => entity.cardId === CardIds.SoulJuggler_BGS_002);\r\n\tfor (const juggler of jugglers) {\r\n\t\tconst target = getRandomMinionWithHighestHealth(boardToAttack);\r\n\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\tjuggler,\r\n\t\t\ttarget,\r\n\t\t\tboardWithJugglers,\r\n\t\t\tboardWithJugglersHero,\r\n\t\t\tboardToAttackHero,\r\n\t\t);\r\n\t\tdealDamageToMinion(\r\n\t\t\ttarget,\r\n\t\t\tboardToAttack,\r\n\t\t\tboardToAttackHero,\r\n\t\t\tjuggler,\r\n\t\t\t4,\r\n\t\t\tboardWithJugglers,\r\n\t\t\tboardWithJugglersHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n\tconst goldenJugglers = boardWithJugglers.filter((entity) => entity.cardId === CardIds.SoulJuggler_TB_BaconUps_075);\r\n\tfor (const juggler of goldenJugglers) {\r\n\t\tfor (let i = 0; i < 2; i++) {\r\n\t\t\tconst target = getRandomMinionWithHighestHealth(boardToAttack);\r\n\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\tjuggler,\r\n\t\t\t\ttarget,\r\n\t\t\t\tboardWithJugglers,\r\n\t\t\t\tboardWithJugglersHero,\r\n\t\t\t\tboardToAttackHero,\r\n\t\t\t);\r\n\t\t\tdealDamageToMinion(\r\n\t\t\t\ttarget,\r\n\t\t\t\tboardToAttack,\r\n\t\t\t\tboardToAttackHero,\r\n\t\t\t\tjuggler,\r\n\t\t\t\t4,\r\n\t\t\t\tboardWithJugglers,\r\n\t\t\t\tboardWithJugglersHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\t// processMinionDeath(\r\n\t// \tboardWithJugglers,\r\n\t// \tboardWithJugglersHero,\r\n\t// \tboardToAttack,\r\n\t// \tboardToAttackHero,\r\n\t// \tallCards,\r\n\t// \tcardsData,\r\n\t// \tsharedState,\r\n\t// \tspectator,\r\n\t// );\r\n};\r\n\r\nconst applyScavengingHyenaEffect = (\r\n\tboard: BoardEntity[],\r\n\tboardWithDeadEntityHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// const copy = [...board];\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].cardId === CardIds.ScavengingHyenaLegacy_BG_EX1_531) {\r\n\t\t\tmodifyStats(board[i], null, 2, 1, board, boardWithDeadEntityHero, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t} else if (board[i].cardId === CardIds.ScavengingHyenaLegacy_TB_BaconUps_043) {\r\n\t\t\tmodifyStats(board[i], null, 4, 2, board, boardWithDeadEntityHero, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyEternalKnightEffect = (board: BoardEntity[], hero: BgsPlayerEntity, gameState: FullGameState): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (\r\n\t\t\tboard[i].cardId === CardIds.EternalKnight_BG25_008 ||\r\n\t\t\tboard[i].cardId === CardIds.EternalKnight_BG25_008_G\r\n\t\t) {\r\n\t\t\tconst multiplier = board[i].cardId === CardIds.EternalKnight_BG25_008_G ? 2 : 1;\r\n\t\t\tmodifyStats(\r\n\t\t\t\tboard[i],\r\n\t\t\t\tnull,\r\n\t\t\t\tmultiplier * eternalKnightAttack,\r\n\t\t\t\tmultiplier * eternalKnightHealth,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyRotHideGnollEffect = (board: BoardEntity[], hero: BgsPlayerEntity, gameState: FullGameState): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].cardId === CardIds.RotHideGnoll_BG25_013 || board[i].cardId === CardIds.RotHideGnoll_BG25_013_G) {\r\n\t\t\tconst multiplier = board[i].cardId === CardIds.RotHideGnoll_BG25_013_G ? 2 : 1;\r\n\t\t\tmodifyStats(board[i], null, multiplier * 1, 0, board, hero, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, null, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyBristlemaneScrapsmithEffect = (\r\n\tboard: BoardEntity[],\r\n\tboardPlayerEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (\r\n\t\t\tboard[i].cardId === CardIds.BristlemaneScrapsmith_BG24_707 ||\r\n\t\t\tboard[i].cardId === CardIds.BristlemaneScrapsmith_BG24_707_G\r\n\t\t) {\r\n\t\t\tconst cardsToAdd = Array(CardIds.BristlemaneScrapsmith_BG24_707_G ? 2 : 1).fill(CardIds.BloodGem);\r\n\t\t\taddCardsInHand(boardPlayerEntity, board, cardsToAdd, gameState);\r\n\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, boardPlayerEntity, null);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyMossOfTheSchlossEffect = (\r\n\tdeadEntity: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tboard\r\n\t\t.filter(\r\n\t\t\t(e) => e.cardId === CardIds.MossOfTheSchloss_BG30_111 || e.cardId === CardIds.MossOfTheSchloss_BG30_111_G,\r\n\t\t)\r\n\t\t.filter((e) => e.abiityChargesLeft > 0)\r\n\t\t.forEach((entity) => {\r\n\t\t\tmodifyStats(entity, null, deadEntity.maxAttack, deadEntity.maxHealth, board, hero, gameState);\r\n\t\t\tentity.abiityChargesLeft--;\r\n\t\t\tgameState.spectator.registerPowerTarget(entity, entity, board, null, null);\r\n\t\t});\r\n};\r\n\r\nconst applyJunkbotEffect = (board: BoardEntity[], hero: BgsPlayerEntity, gameState: FullGameState): void => {\r\n\tfor (let i = 0; i < board.length; i++) {\r\n\t\tif (board[i].cardId === CardIds.Junkbot_GVG_106) {\r\n\t\t\tmodifyStats(board[i], board[i], 2, 2, board, hero, gameState);\r\n\t\t\t// } else if (board[i].cardId === CardIds.Junkbot_TB_BaconUps_046) {\r\n\t\t\t// \tmodifyStats(board[i], board[i], 4, 4, board, hero, gameState);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst applyQirajiHarbringerEffect = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdeadEntityIndexFromRight: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// const qiraji = board.filter((entity) => entity.cardId === CardIds.QirajiHarbinger_BGS_112);\r\n\t// const goldenQiraji = board.filter((entity) => entity.cardId === CardIds.QirajiHarbinger_TB_BaconUps_303);\r\n\t// // TODO: if reactivated, properly apply buffs one by one, instead of all together\r\n\t// if (qiraji.length + goldenQiraji.length > 0) {\r\n\t// \tconst neighbours = getNeighbours(board, null, deadEntityIndexFromRight);\r\n\t// \tconst buff = 2 * qiraji.length + 4 * goldenQiraji.length;\r\n\t// \tneighbours.forEach((entity) => {\r\n\t// \t\tmodifyStats(entity, null, buff, buff, board, hero, gameState);\r\n\t// \t});\r\n\t// }\r\n};\r\n\r\nexport const rememberDeathrattles = (\r\n\tfish: BoardEntity,\r\n\tinputDeadEntities: readonly BoardEntity[],\r\n\tcardsData: CardsData,\r\n\tallCards: AllCardsService,\r\n\tsharedState: SharedState,\r\n): void => {\r\n\tconst deadEntities = inputDeadEntities.filter((e) => !isFish(e));\r\n\tif (!deadEntities?.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\t// Some infinite loops going on?\r\n\tif (fish.rememberedDeathrattles?.length > 100) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst debug = deadEntities.some((e) => e.cardId === CardIds.CorruptedBristler_BG32_431);\r\n\r\n\tconst validDeathrattles = deadEntities\r\n\t\t.filter((entity) => allCards.getCard(entity.cardId).mechanics?.includes(GameTag[GameTag.DEATHRATTLE]))\r\n\t\t.filter((e) => !DEATHRATTLES_REQUIRE_MEMORY.includes(e.cardId as CardIds) || e.memory)\r\n\t\t.map((entity) => ({\r\n\t\t\tcardId: entity.cardId,\r\n\t\t\trepeats: 1,\r\n\t\t\ttiming: sharedState.currentEntityId++,\r\n\t\t\tmemory: entity.memory,\r\n\t\t\tscriptDataNum1: entity.scriptDataNum1,\r\n\t\t\tscriptDataNum2: entity.scriptDataNum2,\r\n\t\t}));\r\n\tconst validEnchantments = deadEntities\r\n\t\t.map((entity) => entity.enchantments)\r\n\t\t.reduce((a, b) => a.concat(b), [])\r\n\t\t.flatMap((enchantment) => ({\r\n\t\t\tcardId: enchantment.cardId,\r\n\t\t\trepeats: enchantment.repeats ?? 1,\r\n\t\t\ttiming: sharedState.currentEntityId++,\r\n\t\t}))\r\n\t\t.filter((enchantment) => isValidDeathrattleEnchantment(enchantment.cardId));\r\n\t// Multiple fish\r\n\tconst deadEntityRememberedDeathrattles =\r\n\t\tdeadEntities\r\n\t\t\t.filter((e) => !!e.rememberedDeathrattles?.length)\r\n\t\t\t// If the fish has reborn, it will inherit its own Deathrattles, and we don't want that\r\n\t\t\t.filter((e) => e.entityId !== fish.rebornFromEntityId)\r\n\t\t\t.filter((e) => !DEATHRATTLES_REQUIRE_MEMORY.includes(e.cardId as CardIds) || e.memory)\r\n\t\t\t.flatMap((e) => e.rememberedDeathrattles) ?? [];\r\n\tconst newDeathrattles = [...validDeathrattles, ...validEnchantments, ...deadEntityRememberedDeathrattles];\r\n\r\n\tif (newDeathrattles.length > 0) {\r\n\t\t// Order is important - the DR are triggered in the order d the minions have died\r\n\t\t// The \"golden\" part is handled at the card level for the other non-fish cards, like Piloted Whirl-o-Tron\r\n\t\tif (isFish(fish) && isGolden(fish.cardId, allCards)) {\r\n\t\t\t// https://stackoverflow.com/questions/33305152/how-to-duplicate-elements-in-a-js-array\r\n\t\t\tconst doubleDr = newDeathrattles.reduce((res, current) => res.concat([current, current]), []);\r\n\t\t\tfish.rememberedDeathrattles = [...(fish.rememberedDeathrattles || []), ...doubleDr];\r\n\t\t} else {\r\n\t\t\tfish.rememberedDeathrattles = [...(fish.rememberedDeathrattles || []), ...newDeathrattles];\r\n\t\t}\r\n\r\n\t\tif (newDeathrattles.some((d) => d.cardId?.startsWith(CardIds.Leapfrogger_BG21_000))) {\r\n\t\t\t// Not sure exactly why, but if a leapfrogger dies first, then a manasaber,\r\n\t\t\t// when the fish dies, the manasaber's effect (spawning tokens) is triggered first\r\n\t\t\t// https://replays.firestoneapp.com/?reviewId=521733fb-8ba1-4663-9a87-3da58e8a09c8&turn=21&action=3\r\n\t\t\t// HACK: So I will hardcode a rule for now to put leapfrogger effects last\r\n\t\t\tconst leapfroggerDeathrattles = groupLeapfroggerDeathrattles(fish.rememberedDeathrattles);\r\n\t\t\tfish.rememberedDeathrattles = [\r\n\t\t\t\t...fish.rememberedDeathrattles.filter((d) => !d.cardId?.startsWith(CardIds.Leapfrogger_BG21_000)),\r\n\t\t\t\t...leapfroggerDeathrattles,\r\n\t\t\t];\r\n\t\t}\r\n\t}\r\n\t// console.debug(\r\n\t// \t'remembered',\r\n\t// \tfish.cardId,\r\n\t// \tfish.entityId,\r\n\t// \tfish.rememberedDeathrattles.map((d) => ({\r\n\t// \t\tcardId: d.cardId,\r\n\t// \t\tname: allCards.getCard(d.cardId)?.name,\r\n\t// \t\t// repeats: d.repeats,\r\n\t// \t\t// timing: d.timing,\r\n\t// \t})),\r\n\t// );\r\n};\r\n\r\nconst removeOldMurkEyeAttack = (\r\n\tboardWithDeadEntity: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\t// const murkeyes = boardWithDeadEntity.filter(\r\n\t// \t(entity) => entity.cardId === CardIds.OldMurkEyeLegacy || entity.cardId === CardIds.OldMurkEyeVanilla,\r\n\t// );\r\n\t// const goldenMurkeyes = boardWithDeadEntity.filter((entity) => entity.cardId === CardIds.OldMurkEye);\r\n\t// murkeyes.forEach((entity) => {\r\n\t// \tmodifyStats(entity, null, -1, 0, boardWithDeadEntity, hero, gameState);\r\n\t// });\r\n\t// goldenMurkeyes.forEach((entity) => {\r\n\t// \tmodifyStats(entity, null, -2, 0, boardWithDeadEntity, hero, gameState);\r\n\t// });\r\n};\r\n"]}
|