@firestone-hs/simulate-bgs-battle 1.1.740 → 1.1.741
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/cards/impl/minion/boom-in-a-box.js.map +1 -1
- package/dist/input-sanitation.js +3 -5
- package/dist/input-sanitation.js.map +1 -1
- package/dist/simulation/attack.js +3 -0
- package/dist/simulation/attack.js.map +1 -1
- package/dist/simulation/auras.d.ts +1 -1
- package/dist/simulation/auras.js +66 -53
- package/dist/simulation/auras.js.map +1 -1
- package/dist/simulation/deathrattle-utils.js +6 -3
- package/dist/simulation/deathrattle-utils.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +5 -1
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boom-in-a-box.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/boom-in-a-box.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"boom-in-a-box.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/boom-in-a-box.ts"],"names":[],"mappings":";;;AASA,uDAAgE;AAIhE,MAAM,MAAM,GAAG,CAAC,CAAC;AAEJ,QAAA,UAAU,GAAsB;IAC5C,OAAO,EAAE,0BAA4D;IACrE,mBAAmB,EAAE,iBAAiB;IACtC,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,iBAAkC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QAC3F,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC;YACvD,IAAA,2BAAkB,EACjB,MAAM,EACN,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,EACpD,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,EACtD,MAAM,EACN,MAAM,GAAG,IAAI,EACb,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EACpD,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,EACtD,KAAK,CAAC,SAAS,CACf,CAAC;SACF;QACD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;CACD,CAAC","sourcesContent":["/**\r\n * Boom-in-a-Box (Tier 4, 5/10)\r\n * Taunt. Start of Combat: Deal 3 damage to all other minions.\r\n *\r\n * Golden Boom-in-a-Box (Tier 4, 10/20)\r\n * Taunt. Start of Combat: Deal 6 damage to all other minions.\r\n */\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { dealDamageToMinion } from '../../../simulation/attack';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nconst damage = 3;\r\n\r\nexport const BoomInABox: StartOfCombatCard = {\r\n\tcardIds: [CardIds.BoomInABox_BG36_620, CardIds.BoomInABox_BG36_620_G],\r\n\tstartOfCombatTiming: 'start-of-combat',\r\n\tstartOfCombat: (minion: BoardEntity, input: SoCInput) => {\r\n\t\tconst mult = minion.cardId === CardIds.BoomInABox_BG36_620_G ? 2 : 1;\r\n\t\tconst targets = [...input.playerBoard, ...input.opponentBoard].filter((e) => e !== minion);\r\n\t\tfor (const target of targets) {\r\n\t\t\tconst isSameSide = target.friendly === minion.friendly;\r\n\t\t\tdealDamageToMinion(\r\n\t\t\t\ttarget,\r\n\t\t\t\tisSameSide ? input.playerBoard : input.opponentBoard,\r\n\t\t\t\tisSameSide ? input.playerEntity : input.opponentEntity,\r\n\t\t\t\tminion,\r\n\t\t\t\tdamage * mult,\r\n\t\t\t\tisSameSide ? input.opponentBoard : input.playerBoard,\r\n\t\t\t\tisSameSide ? input.opponentEntity : input.playerEntity,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true };\r\n\t},\r\n};\r\n"]}
|
package/dist/input-sanitation.js
CHANGED
|
@@ -56,7 +56,7 @@ const buildFinalInput = (battleInput, cards, cardsData) => {
|
|
|
56
56
|
};
|
|
57
57
|
exports.buildFinalInput = buildFinalInput;
|
|
58
58
|
const buildFinalInputForPlayer = (playerInfo, isPlayer, anomalies, cards, cardsData, entityIdContainer) => {
|
|
59
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
59
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
60
60
|
if (!playerInfo) {
|
|
61
61
|
return { board: [], hand: [], player: null };
|
|
62
62
|
}
|
|
@@ -67,9 +67,7 @@ const buildFinalInputForPlayer = (playerInfo, isPlayer, anomalies, cards, cardsD
|
|
|
67
67
|
playerInfo.player.trinkets = (fixedTrinkets !== null && fixedTrinkets !== void 0 ? fixedTrinkets : []).sort((a, b) => a.entityId - b.entityId);
|
|
68
68
|
playerInfo.player.friendly = isPlayer;
|
|
69
69
|
playerInfo.player.globalInfo = (_f = playerInfo.player.globalInfo) !== null && _f !== void 0 ? _f : {};
|
|
70
|
-
playerInfo.player.
|
|
71
|
-
playerInfo.player.globalInfo.MechAttackBonus = (_h = playerInfo.player.globalInfo.MechAttackBonus) !== null && _h !== void 0 ? _h : 0;
|
|
72
|
-
playerInfo.player.heroPowers = ((_j = playerInfo.player.heroPowers) === null || _j === void 0 ? void 0 : _j.length)
|
|
70
|
+
playerInfo.player.heroPowers = ((_g = playerInfo.player.heroPowers) === null || _g === void 0 ? void 0 : _g.length)
|
|
73
71
|
? playerInfo.player.heroPowers.map((hp, index) => sanitizeHeroPower(hp, index, playerInfo.player, cards))
|
|
74
72
|
: [
|
|
75
73
|
{
|
|
@@ -83,7 +81,7 @@ const buildFinalInputForPlayer = (playerInfo, isPlayer, anomalies, cards, cardsD
|
|
|
83
81
|
playerInfo.player.cardId = isGhost ? "TB_BaconShop_HERO_KelThuzad" : playerInfo.player.cardId;
|
|
84
82
|
playerInfo.player.hpLeft = Math.max(1, playerInfo.player.hpLeft);
|
|
85
83
|
(0, auras_1.setMissingAuras)(board, playerInfo.player, anomalies, cards);
|
|
86
|
-
(0, auras_1.setImplicitDataHero)(playerInfo.player, cardsData, isPlayer, entityIdContainer);
|
|
84
|
+
(0, auras_1.setImplicitDataHero)(playerInfo.player, board, cardsData, isPlayer, entityIdContainer);
|
|
87
85
|
return { board, hand, player: playerInfo.player };
|
|
88
86
|
};
|
|
89
87
|
const sanitizeHeroPower = (hp, index, player, cards) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-sanitation.js","sourceRoot":"","sources":["../src/input-sanitation.ts"],"names":[],"mappings":"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","sourcesContent":["import { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BgsBoardInfo } from './bgs-board-info';\r\nimport { BgsHeroPower, BgsPlayerEntity } from './bgs-player-entity';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { CardIds } from './services/card-ids';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { fixEnchantments } from './simulation/enchantments';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nexport const buildFinalInput = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): BgsBattleInfo => {\r\n\tconst entityIdContainer = { entityId: 999_999_999 };\r\n\r\n\tconst {\r\n\t\tboard: playerBoard,\r\n\t\thand: playerHand,\r\n\t\tplayer: playerEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: playerTeammateBoard,\r\n\t\thand: playerTeammateHand,\r\n\t\tplayer: playerTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerTeammateBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\tconst {\r\n\t\tboard: opponentBoard,\r\n\t\thand: opponentHand,\r\n\t\tplayer: opponentEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: opponentTeammateBoard,\r\n\t\thand: opponentTeammateHand,\r\n\t\tplayer: opponentTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentTeammateBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerEntity,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tplayerTeammateBoard: !!playerTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: playerTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...playerTeammateEntity,\r\n\t\t\t\t\t\thand: playerTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentEntity,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentTeammateBoard: !!opponentTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: opponentTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...opponentTeammateEntity,\r\n\t\t\t\t\t\thand: opponentTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\tgameState: {\r\n\t\t\t...battleInput.gameState,\r\n\t\t\tanomalies: battleInput.gameState.anomalies?.filter((a) => !!a) ?? ([] as readonly string[]),\r\n\t\t},\r\n\t\t// Combat-affecting options (e.g. applyDamageCap) must survive into runSingleBattle;\r\n\t\t// Monte Carlo knobs are still read from the original battleInput before cloning.\r\n\t\toptions: battleInput.options,\r\n\t\theroHasDied: battleInput.heroHasDied,\r\n\t\tdebugState: battleInput.debugState,\r\n\t} as BgsBattleInfo;\r\n\treturn inputReady;\r\n};\r\n\r\nconst buildFinalInputForPlayer = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tanomalies: readonly string[],\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tentityIdContainer: { entityId: number },\r\n): { board: BoardEntity[]; hand: BoardEntity[]; player: BgsPlayerEntity } => {\r\n\tif (!playerInfo) {\r\n\t\treturn { board: [], hand: [], player: null };\r\n\t}\r\n\r\n\tconst { board, hand } = buildFinalInputBoard(playerInfo, isPlayer, cardsData, cards);\r\n\tconst isGhost = playerInfo.player?.hpLeft != null && playerInfo.player.hpLeft <= 0;\r\n\tplayerInfo.player.secrets = (playerInfo.player.secrets ?? playerInfo.secrets)?.filter((e) => !!e?.cardId) ?? [];\r\n\t// Add the scriptDataNum1 only on the start of combat phase, so that it doesn't trigger too soon\r\n\t// Don't do this, as secrets like Fleeting Vigor use this info to tell how much buff it will apply\r\n\t// playerInfo.player.secrets.forEach((secret) => (secret.scriptDataNum1 = 0));\r\n\t// Trinkets don't seem to trigger when facing the ghost\r\n\t// http://replays.firestoneapp.com/?reviewId=4ad32e03-2620-4fb1-8b43-cad55afd30fc&turn=27&action=2\r\n\t// One of the trinkets is Blood Golem Sticker, and no Blood Golem is summoned\r\n\t// Looks like that's not always the case:\r\n\t// http://replays.firestoneapp.com/?reviewId=9958e8d3-4388-4e6f-9b36-35f3a08be2f6&turn=25&action=4\r\n\t// playerInfo.player.trinkets = isGhost ? [] : playerInfo.player.trinkets?.filter((e) => !!e?.cardId) ?? [];\r\n\tconst fixedTrinkets = playerInfo.player.trinkets?.filter((e) => !!e?.cardId);\r\n\tplayerInfo.player.trinkets = (fixedTrinkets ?? []).sort((a, b) => a.entityId - b.entityId);\r\n\tplayerInfo.player.friendly = isPlayer;\r\n\tplayerInfo.player.globalInfo = playerInfo.player.globalInfo ?? {};\r\n\tplayerInfo.player.globalInfo.PirateAttackBonus = playerInfo.player.globalInfo.PirateAttackBonus ?? 0;\r\n\tplayerInfo.player.globalInfo.MechAttackBonus = playerInfo.player.globalInfo.MechAttackBonus ?? 0;\r\n\tplayerInfo.player.heroPowers = playerInfo.player.heroPowers?.length\r\n\t\t? playerInfo.player.heroPowers.map((hp, index) => sanitizeHeroPower(hp, index, playerInfo.player, cards))\r\n\t\t: [\r\n\t\t\t\t{\r\n\t\t\t\t\tcardId: playerInfo.player.heroPowerId,\r\n\t\t\t\t\tentityId: playerInfo.player.heroPowerEntityId,\r\n\t\t\t\t\tused: playerInfo.player.heroPowerUsed,\r\n\t\t\t\t\tinfo: playerInfo.player.heroPowerInfo,\r\n\t\t\t\t\tinfo2: playerInfo.player.heroPowerInfo2,\r\n\t\t\t\t} as BgsHeroPower,\r\n\t\t ];\r\n\t// playerInfo.player.heroPowerId =\r\n\t// \tplayerInfo.player.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(playerInfo.player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? playerInfo.player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \tplayerInfo.player.heroPowerId;\r\n\tplayerInfo.player.cardId = isGhost ? CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad : playerInfo.player.cardId;\r\n\tplayerInfo.player.hpLeft = Math.max(1, playerInfo.player.hpLeft);\r\n\t// When using the simulator, the aura is not applied when receiving the board state.\r\n\tsetMissingAuras(board, playerInfo.player, anomalies, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, cardsData, isPlayer, entityIdContainer);\r\n\treturn { board, hand, player: playerInfo.player };\r\n};\r\n\r\nconst sanitizeHeroPower = (\r\n\thp: BgsHeroPower,\r\n\tindex: number,\r\n\tplayer: BgsPlayerEntity,\r\n\tcards: AllCardsService,\r\n): BgsHeroPower => {\r\n\treturn hp;\r\n\t// FIXME: fix this when the situation presents itself. At the moment, we already have trinkets / hero powers / quest rewards\r\n\t// handled separately, so maybe there is no need to map a quest reward to one of Sire D.'s hero power\r\n\t// if (index !== 0) {\r\n\t// \treturn hp;\r\n\t// }\r\n\r\n\t// hp.cardId =\r\n\t// \tplayer.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \thp.cardId;\r\n\t// return hp;\r\n};\r\n\r\nconst sanitizeEntity = (\r\n\tentity: BoardEntity,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n\tapplyDefaultScriptData: boolean,\r\n): BoardEntity => {\r\n\tconst fixed = fixEnchantments(entity, cards);\r\n\tfixed.inInitialState = true;\r\n\tif (applyDefaultScriptData) {\r\n\t\tfixed.scriptDataNum1 = cardsData.defaultScriptDataNum(fixed.cardId) || fixed.scriptDataNum1;\r\n\t}\r\n\taddImpliedMechanics(fixed, cardsData);\r\n\tfixed.friendly = isPlayer;\r\n\t// Used for Persisting Horror\r\n\tfixed.hadVenomous = fixed.venomous;\r\n\treturn fixed;\r\n};\r\n\r\nconst buildFinalInputBoard = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n): { board: BoardEntity[]; hand: BoardEntity[] } => {\r\n\tconst board = playerInfo.board.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, true));\r\n\tconst hand =\r\n\t\tplayerInfo.player.hand?.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, false)) ?? [];\r\n\treturn { board, hand };\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"input-sanitation.js","sourceRoot":"","sources":["../src/input-sanitation.ts"],"names":[],"mappings":";;;AAOA,8CAA0E;AAC1E,4DAA4D;AAC5D,mCAA8C;AAEvC,MAAM,eAAe,GAAG,CAC9B,WAA0B,EAC1B,KAAsB,EACtB,SAAoB,EACJ,EAAE;;IAClB,MAAM,iBAAiB,GAAG,EAAE,QAAQ,EAAE,SAAW,EAAE,CAAC;IAEpD,MAAM,EACL,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,YAAY,GACpB,GAAG,wBAAwB,CAC3B,WAAW,CAAC,WAAW,EACvB,IAAI,EACJ,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IACF,MAAM,EACL,KAAK,EAAE,mBAAmB,EAC1B,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,oBAAoB,GAC5B,GAAG,wBAAwB,CAC3B,WAAW,CAAC,mBAAmB,EAC/B,IAAI,EACJ,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IAEF,MAAM,EACL,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACtB,GAAG,wBAAwB,CAC3B,WAAW,CAAC,aAAa,EACzB,KAAK,EACL,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IACF,MAAM,EACL,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,sBAAsB,GAC9B,GAAG,wBAAwB,CAC3B,WAAW,CAAC,qBAAqB,EACjC,KAAK,EACL,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IAIF,MAAM,UAAU,GAAkB;QACjC,WAAW,EAAE;YACZ,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE;gBACP,GAAG,YAAY;gBACf,IAAI,EAAE,UAAU;aAChB;SACD;QACD,mBAAmB,EAAE,CAAC,CAAC,oBAAoB;YAC1C,CAAC,CAAC;gBACA,KAAK,EAAE,mBAAmB;gBAC1B,MAAM,EAAE;oBACP,GAAG,oBAAoB;oBACvB,IAAI,EAAE,kBAAkB;iBACxB;aACA;YACH,CAAC,CAAC,IAAI;QACP,aAAa,EAAE;YACd,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE;gBACP,GAAG,cAAc;gBACjB,IAAI,EAAE,YAAY;aAClB;SACD;QACD,qBAAqB,EAAE,CAAC,CAAC,sBAAsB;YAC9C,CAAC,CAAC;gBACA,KAAK,EAAE,qBAAqB;gBAC5B,MAAM,EAAE;oBACP,GAAG,sBAAsB;oBACzB,IAAI,EAAE,oBAAoB;iBAC1B;aACA;YACH,CAAC,CAAC,IAAI;QACP,SAAS,EAAE;YACV,GAAG,WAAW,CAAC,SAAS;YACxB,SAAS,EAAE,MAAA,MAAA,WAAW,CAAC,SAAS,CAAC,SAAS,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,mCAAK,EAAwB;SAC3F;QAGD,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,WAAW,EAAE,WAAW,CAAC,WAAW;QACpC,UAAU,EAAE,WAAW,CAAC,UAAU;KACjB,CAAC;IACnB,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AAvGW,QAAA,eAAe,mBAuG1B;AAEF,MAAM,wBAAwB,GAAG,CAChC,UAAwB,EACxB,QAAiB,EACjB,SAA4B,EAC5B,KAAsB,EACtB,SAAoB,EACpB,iBAAuC,EACkC,EAAE;;IAC3E,IAAI,CAAC,UAAU,EAAE;QAChB,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;KAC7C;IAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,oBAAoB,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,CAAA,MAAA,UAAU,CAAC,MAAM,0CAAE,MAAM,KAAI,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACnF,UAAU,CAAC,MAAM,CAAC,OAAO,GAAG,MAAA,MAAA,CAAC,MAAA,UAAU,CAAC,MAAM,CAAC,OAAO,mCAAI,UAAU,CAAC,OAAO,CAAC,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,mCAAI,EAAE,CAAC;IAUhH,MAAM,aAAa,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,QAAQ,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,CAAC;IAC7E,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3F,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACtC,UAAU,CAAC,MAAM,CAAC,UAAU,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,UAAU,mCAAI,EAAE,CAAC;IAClE,UAAU,CAAC,MAAM,CAAC,UAAU,GAAG,CAAA,MAAA,UAAU,CAAC,MAAM,CAAC,UAAU,0CAAE,MAAM;QAClE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACzG,CAAC,CAAC;YACA;gBACC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,WAAW;gBACrC,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,iBAAiB;gBAC7C,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,aAAa;gBACrC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,aAAa;gBACrC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,cAAc;aACvB;SAChB,CAAC;IAOL,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,+BAA+C,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9G,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEjE,IAAA,uBAAe,EAAC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAK5D,IAAA,2BAAmB,EAAC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IACtF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AACnD,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CACzB,EAAgB,EAChB,KAAa,EACb,MAAuB,EACvB,KAAsB,EACP,EAAE;IACjB,OAAO,EAAE,CAAC;AAcX,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACtB,MAAmB,EACnB,QAAiB,EACjB,SAAoB,EACpB,KAAsB,EACtB,sBAA+B,EACjB,EAAE;IAChB,MAAM,KAAK,GAAG,IAAA,8BAAe,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7C,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;IAC5B,IAAI,sBAAsB,EAAE;QAC3B,KAAK,CAAC,cAAc,GAAG,SAAS,CAAC,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC;KAC5F;IACD,IAAA,2BAAmB,EAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACtC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAE1B,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC;IACnC,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAC5B,UAAwB,EACxB,QAAiB,EACjB,SAAoB,EACpB,KAAsB,EAC0B,EAAE;;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACzG,MAAM,IAAI,GACT,MAAA,MAAA,UAAU,CAAC,MAAM,CAAC,IAAI,0CAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,mCAAI,EAAE,CAAC;IAC1G,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC,CAAC","sourcesContent":["import { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BgsBoardInfo } from './bgs-board-info';\r\nimport { BgsHeroPower, BgsPlayerEntity } from './bgs-player-entity';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { CardIds } from './services/card-ids';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { fixEnchantments } from './simulation/enchantments';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nexport const buildFinalInput = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): BgsBattleInfo => {\r\n\tconst entityIdContainer = { entityId: 999_999_999 };\r\n\r\n\tconst {\r\n\t\tboard: playerBoard,\r\n\t\thand: playerHand,\r\n\t\tplayer: playerEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: playerTeammateBoard,\r\n\t\thand: playerTeammateHand,\r\n\t\tplayer: playerTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerTeammateBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\tconst {\r\n\t\tboard: opponentBoard,\r\n\t\thand: opponentHand,\r\n\t\tplayer: opponentEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: opponentTeammateBoard,\r\n\t\thand: opponentTeammateHand,\r\n\t\tplayer: opponentTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentTeammateBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerEntity,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tplayerTeammateBoard: !!playerTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: playerTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...playerTeammateEntity,\r\n\t\t\t\t\t\thand: playerTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentEntity,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentTeammateBoard: !!opponentTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: opponentTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...opponentTeammateEntity,\r\n\t\t\t\t\t\thand: opponentTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\tgameState: {\r\n\t\t\t...battleInput.gameState,\r\n\t\t\tanomalies: battleInput.gameState.anomalies?.filter((a) => !!a) ?? ([] as readonly string[]),\r\n\t\t},\r\n\t\t// Combat-affecting options (e.g. applyDamageCap) must survive into runSingleBattle;\r\n\t\t// Monte Carlo knobs are still read from the original battleInput before cloning.\r\n\t\toptions: battleInput.options,\r\n\t\theroHasDied: battleInput.heroHasDied,\r\n\t\tdebugState: battleInput.debugState,\r\n\t} as BgsBattleInfo;\r\n\treturn inputReady;\r\n};\r\n\r\nconst buildFinalInputForPlayer = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tanomalies: readonly string[],\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tentityIdContainer: { entityId: number },\r\n): { board: BoardEntity[]; hand: BoardEntity[]; player: BgsPlayerEntity } => {\r\n\tif (!playerInfo) {\r\n\t\treturn { board: [], hand: [], player: null };\r\n\t}\r\n\r\n\tconst { board, hand } = buildFinalInputBoard(playerInfo, isPlayer, cardsData, cards);\r\n\tconst isGhost = playerInfo.player?.hpLeft != null && playerInfo.player.hpLeft <= 0;\r\n\tplayerInfo.player.secrets = (playerInfo.player.secrets ?? playerInfo.secrets)?.filter((e) => !!e?.cardId) ?? [];\r\n\t// Add the scriptDataNum1 only on the start of combat phase, so that it doesn't trigger too soon\r\n\t// Don't do this, as secrets like Fleeting Vigor use this info to tell how much buff it will apply\r\n\t// playerInfo.player.secrets.forEach((secret) => (secret.scriptDataNum1 = 0));\r\n\t// Trinkets don't seem to trigger when facing the ghost\r\n\t// http://replays.firestoneapp.com/?reviewId=4ad32e03-2620-4fb1-8b43-cad55afd30fc&turn=27&action=2\r\n\t// One of the trinkets is Blood Golem Sticker, and no Blood Golem is summoned\r\n\t// Looks like that's not always the case:\r\n\t// http://replays.firestoneapp.com/?reviewId=9958e8d3-4388-4e6f-9b36-35f3a08be2f6&turn=25&action=4\r\n\t// playerInfo.player.trinkets = isGhost ? [] : playerInfo.player.trinkets?.filter((e) => !!e?.cardId) ?? [];\r\n\tconst fixedTrinkets = playerInfo.player.trinkets?.filter((e) => !!e?.cardId);\r\n\tplayerInfo.player.trinkets = (fixedTrinkets ?? []).sort((a, b) => a.entityId - b.entityId);\r\n\tplayerInfo.player.friendly = isPlayer;\r\n\tplayerInfo.player.globalInfo = playerInfo.player.globalInfo ?? {};\r\n\tplayerInfo.player.heroPowers = playerInfo.player.heroPowers?.length\r\n\t\t? playerInfo.player.heroPowers.map((hp, index) => sanitizeHeroPower(hp, index, playerInfo.player, cards))\r\n\t\t: [\r\n\t\t\t\t{\r\n\t\t\t\t\tcardId: playerInfo.player.heroPowerId,\r\n\t\t\t\t\tentityId: playerInfo.player.heroPowerEntityId,\r\n\t\t\t\t\tused: playerInfo.player.heroPowerUsed,\r\n\t\t\t\t\tinfo: playerInfo.player.heroPowerInfo,\r\n\t\t\t\t\tinfo2: playerInfo.player.heroPowerInfo2,\r\n\t\t\t\t} as BgsHeroPower,\r\n\t\t ];\r\n\t// playerInfo.player.heroPowerId =\r\n\t// \tplayerInfo.player.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(playerInfo.player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? playerInfo.player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \tplayerInfo.player.heroPowerId;\r\n\tplayerInfo.player.cardId = isGhost ? CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad : playerInfo.player.cardId;\r\n\tplayerInfo.player.hpLeft = Math.max(1, playerInfo.player.hpLeft);\r\n\t// When using the simulator, the aura is not applied when receiving the board state.\r\n\tsetMissingAuras(board, playerInfo.player, anomalies, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, board, cardsData, isPlayer, entityIdContainer);\r\n\treturn { board, hand, player: playerInfo.player };\r\n};\r\n\r\nconst sanitizeHeroPower = (\r\n\thp: BgsHeroPower,\r\n\tindex: number,\r\n\tplayer: BgsPlayerEntity,\r\n\tcards: AllCardsService,\r\n): BgsHeroPower => {\r\n\treturn hp;\r\n\t// FIXME: fix this when the situation presents itself. At the moment, we already have trinkets / hero powers / quest rewards\r\n\t// handled separately, so maybe there is no need to map a quest reward to one of Sire D.'s hero power\r\n\t// if (index !== 0) {\r\n\t// \treturn hp;\r\n\t// }\r\n\r\n\t// hp.cardId =\r\n\t// \tplayer.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \thp.cardId;\r\n\t// return hp;\r\n};\r\n\r\nconst sanitizeEntity = (\r\n\tentity: BoardEntity,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n\tapplyDefaultScriptData: boolean,\r\n): BoardEntity => {\r\n\tconst fixed = fixEnchantments(entity, cards);\r\n\tfixed.inInitialState = true;\r\n\tif (applyDefaultScriptData) {\r\n\t\tfixed.scriptDataNum1 = cardsData.defaultScriptDataNum(fixed.cardId) || fixed.scriptDataNum1;\r\n\t}\r\n\taddImpliedMechanics(fixed, cardsData);\r\n\tfixed.friendly = isPlayer;\r\n\t// Used for Persisting Horror\r\n\tfixed.hadVenomous = fixed.venomous;\r\n\treturn fixed;\r\n};\r\n\r\nconst buildFinalInputBoard = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n): { board: BoardEntity[]; hand: BoardEntity[] } => {\r\n\tconst board = playerInfo.board.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, true));\r\n\tconst hand =\r\n\t\tplayerInfo.player.hand?.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, false)) ?? [];\r\n\treturn { board, hand };\r\n};\r\n"]}
|
|
@@ -270,6 +270,9 @@ const dealDamageToMinion = (target, board, hero, damageSource, damage, otherBoar
|
|
|
270
270
|
}
|
|
271
271
|
if (actualDamageDone > 0) {
|
|
272
272
|
const newSpawns = (0, damage_effects_1.onEntityDamaged)(target, board, hero, otherBoard, otherHero, damageSource, actualDamageDone, gameState);
|
|
273
|
+
if ((0, utils_2.isBoardEntity)(damageSource)) {
|
|
274
|
+
damageSource.venomous = false;
|
|
275
|
+
}
|
|
273
276
|
}
|
|
274
277
|
if (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {
|
|
275
278
|
target.lastAffectedByEntity = damageSource;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attack.js","sourceRoot":"","sources":["../../src/simulation/attack.ts"],"names":[],"mappings":";;;AAIA,4DAAsE;AACtE,iEAA4D;AAC5D,gDAA4C;AAC5C,6DAA+D;AAC/D,mDAAsD;AAEtD,6CAAgE;AAChE,oCAAuD;AACvD,iDAAmF;AACnF,qDAAmD;AACnD,+DAA6D;AAC7D,2EAA4E;AAC5E,6DAAqD;AAErD,iDAAgD;AAChD,+CAA6C;AAC7C,2CAAmD;AACnD,2DAAgE;AAChE,uDAA0D;AAC1D,qCAA+C;AAC/C,mCAAgD;AAChD,2DAA6D;AAC7D,uDAAiD;AAG1C,MAAM,cAAc,GAAG,CAC7B,cAA6B,EAC7B,kBAAmC,EACnC,cAA6B,EAC7B,kBAAmC,EACnC,SAAwB,EACxB,OAGC,EACa,EAAE;;IAOhB,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/D,OAAO;KACP;IAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,cAAc,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/E,IAAI,eAAe,EAAE;QACpB,SAAS,CAAC,WAAW,CAAC,uBAAuB,GAAG,eAAe,CAAC,QAAQ,CAAC;QAGzE,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACrE,MAAM,0BAA0B,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;QACjF,MAAM,sBAAsB,GAAG,eAAe,CAAC,iBAAiB,CAAC;QAUjE,IAAI,CAAC,sBAAsB,EAAE;YAG5B,0BAA0B,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;SACzE;aAAM;YAEN,eAAe,CAAC,iBAAiB,GAAG,KAAK,CAAC;SAC1C;QAED,MAAM,eAAe,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE;YAEzC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;gBAG/D,MAAM;aACN;YAED,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,eAAe,CAAC,QAAQ,CAAC,EAAE;gBAClF,MAAM,eAAe,GACpB,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,mCAAI,IAAA,0BAAkB,EAAC,cAAc,EAAE,eAAe,CAAC,CAAC;gBAE7E,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE;oBACrF,IAAA,oBAAY,EACX,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,OAAO,CACP,CAAC;iBACF;qBAAM;oBAEN,eAAe,CAAC,iBAAiB,GAAG,KAAK,CAAC;iBAC1C;aACD;SACD;QACD,SAAS,CAAC,WAAW,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACrD,eAAe,CAAC,WAAW,GAAG,CAAC,CAAC;KAChC;IACD,OAAO,eAAe,CAAC;AACxB,CAAC,CAAC;AAjFW,QAAA,cAAc,kBAiFzB;AAEK,MAAM,YAAY,GAAG,CAC3B,eAA4B,EAC5B,cAA6B,EAC7B,kBAAmC,EACnC,eAA4B,EAC5B,cAA6B,EAC7B,kBAAmC,EACnC,SAAwB,EACxB,OAEC,EACA,EAAE;;IACH,MAAM,sBAAsB,GAAG,eAAe,CAAC,iBAAiB,CAAC;IACjE,SAAS,CAAC,SAAS,CAAC,cAAc,CACjC,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,CAClB,CAAC;IAGF,IAAA,6CAAyB,EACxB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;IACF,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GACjG,IAAA,gCAAoB,EACnB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;IACH,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GAAG,aAAa,CACjH,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;IACF,MAAM,oBAAoB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;IAC3E,MAAM,oBAAoB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;IAiB3E,IAAA,sCAAuB,EACtB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,SAAS,CACT,CAAC;IAEF,IAAA,0BAAkB,EACjB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,mBAAmB,KAAI,sBAAsB,CACtD,CAAC;IAEF,IAAA,uCAAwB,EACvB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,SAAS,CACT,CAAC;IACF,IAAA,6BAAqB,EAAC,SAAS,CAAC,CAAC;IACjC,eAAe,CAAC,uBAAuB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAA,eAAe,CAAC,uBAAuB,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAY3G,CAAC,CAAC;AAlHW,QAAA,YAAY,gBAkHvB;AAEF,MAAM,aAAa,GAAG,CACrB,eAA4B,EAC5B,eAA4B,EAC5B,cAA6B,EAC7B,kBAAmC,EACnC,cAA6B,EAC7B,kBAAmC,EACnC,SAAwB,EACyC,EAAE;IACnE,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC;IAE7C,IAAI,0BAA0D,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAiB,CAAC,EAAE;QAC3G,MAAM,MAAM,GAAG,IAAA,kCAAa,EAC3B,eAAe,CAAC,MAAM,iBAAiC;YACtD,CAAC;YACD,CAAC,aAAiC,EACnC,CAAC,EACD,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,IAAI,CACJ,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,IAAA,4BAAmB,EACvC,MAAM,EACN,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;YACF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE;gBACvC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE;oBAClE,aAAa,CACZ,WAAW,EACX,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;iBACF;aACD;SACD;KACD;IAGD,MAAM,yBAAyB,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC;IAEhG,MAAM,uBAAuB,GAAG,eAAe,CAAC,YAAY,CAAC;IAC7D,MAAM,uBAAuB,GAAG,eAAe,CAAC,YAAY,CAAC;IAG7D,MAAM,kBAAkB,GAA2B,IAAA,qBAAa,EAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IAClG,IAAI,yBAAyB,EAAE;QAC9B,IAAI,CAAC,eAAe,CAAC,uBAAuB,EAAE;YAE7C,oBAAoB,IAAI,IAAA,oBAAY,EACnC,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;SACF;QACD,oBAAoB,IAAI,IAAA,oBAAY,EACnC,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;QACF,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAuB,IAAI,CAAC,eAAe,CAAC,uBAAuB,EAAE;YACtG,IAAA,kCAAkB,EACjB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,EACL,SAAS,CACT,CAAC;SACF;QACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAuB,EAAE;YAC1D,IAAA,kCAAkB,EACjB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,EACL,SAAS,CACT,CAAC;SACF;QAID,IAAI,oBAAoB,GAAG,CAAC,EAAE;YAC7B,IAAA,gCAAe,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,SAAS,CACT,CAAC;SACF;QACD,IAAI,oBAAoB,GAAG,CAAC,EAAE;YAC7B,IAAA,gCAAe,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,SAAS,CACT,CAAC;SACF;QAED,IAAI,eAAe,CAAC,MAAM,IAAI,CAAC,IAAI,eAAe,CAAC,cAAc,EAAE;YAClE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,IAAA,0BAAY,EAC5D,eAAe,EACf,IAAI,EACJ,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,CACT,CAAC;YACF,oBAAoB,IAAI,iBAAiB,CAAC;YAC1C,oBAAoB,IAAI,iBAAiB,CAAC;SAC1C;QACD,IAAI,eAAe,CAAC,MAAM,IAAI,CAAC,IAAI,eAAe,CAAC,cAAc,EAAE;YAClE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,IAAA,0BAAY,EAC5D,eAAe,EACf,KAAK,EACL,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,CACT,CAAC;YACF,oBAAoB,IAAI,iBAAiB,CAAC;YAC1C,oBAAoB,IAAI,iBAAiB,CAAC;SAC1C;KACD;IAED,IAAI,eAAe,CAAC,MAAM,EAAE;QAC3B,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE;YAC3C,MAAM,gBAAgB,GAAG,IAAA,oBAAY,EACpC,SAAS,EACT,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,WAAW,CACX,CAAC;YACF,oBAAoB,IAAI,gBAAgB,CAAC;YAGzC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,YAAY,EAAE;gBACzD,IAAA,kCAAkB,EAAC,SAAS,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;aACxG;YACD,IAAI,gBAAgB,GAAG,CAAC,EAAE;gBACzB,IAAA,gCAAe,EACd,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,SAAS,CACT,CAAC;aACF;YACD,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE;gBACtD,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,IAAA,0BAAY,EAC5D,eAAe,EACf,IAAI,EACJ,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,CACT,CAAC;gBACF,oBAAoB,IAAI,iBAAiB,CAAC;gBAC1C,oBAAoB,IAAI,iBAAiB,CAAC;aAC1C;SACD;KACD;IAED,eAAe,CAAC,iBAAiB,GAAG,KAAK,CAAC;IAC1C,IAAI,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,uBAA8C,CAAC,EAAE;QACrG,eAAe,CAAC,cAAc,GAAG,IAAI,CAAC;KACtC;IACD,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;AACvD,CAAC,CAAC;AAIF,MAAM,kBAAkB,GAAG,CAAC,cAA6B,EAAE,QAAyB,EAAe,EAAE;IACpG,IAAI,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,wBAAS,EAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;QAChC,OAAO,IAAI,CAAC;KACZ;IAED,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;QAC9D,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;KAC7E;SAAM,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,EAAE;QAC9D,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC;KAC3D;SAAM;QACN,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,IAAI,SAAS,CAAC,CAAC;KACpF;IACD,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEK,MAAM,kBAAkB,GAAG,CACjC,cAA6B,EAC7B,MAAmB,EACnB,oBAA4B,EAC5B,cAA6B,EAC7B,eAAuB,EACvB,QAAyB,EACT,EAAE;IAClB,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;QAE9B,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,GAAG,oBAAoB,GAAG,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAGxF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE;YACzC,MAAM,eAAe,GAAG,cAAc;iBACpC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;iBAChD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAErC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;gBAC5B,MAAM;aACN;YAED,MAAM,YAAY,GAAG,IAAA,uBAAe,EAAC,CAAC,CAAc,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAC1G,eAAe,CACf,CAAC;YACF,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;iBACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;iBACd,IAAI,EAAE,CAAC;YACT,MAAM,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,eAAe,IAAI,IAAI,EAAE;gBAM5B,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC;gBACzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACpB;SAED;KACD;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC,CAAC;AA5CW,QAAA,kBAAkB,sBA4C7B;AAEK,MAAM,aAAa,GAAG,CAC5B,KAAoB,EACpB,MAAmB,EACnB,wBAAiC,EACjC,iBAAiB,GAAG,KAAK,EACA,EAAE;IAC3B,MAAM,UAAU,GAAG,EAAE,CAAC;IAEtB,IAAI,wBAAwB,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChE,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,wBAAwB,CAAC;QACvE,MAAM,aAAa,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAChD,IAAI,aAAa,EAAE;YAClB,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;SAC/B;QAGD,MAAM,mBAAmB,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,wBAAwB,GAAG,CAAC,CAAC,CAAC;QAC9E,MAAM,cAAc,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAClD,IAAI,cAAc,EAAE;YACnB,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;SAChC;KACD;SAAM;QACN,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrE,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE;YACnB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;SAClC;aAAM,IAAI,iBAAiB,EAAE;YAC7B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACtB;QAED,IAAI,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE;YAC7B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;SAClC;aAAM,IAAI,iBAAiB,EAAE;YAC7B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACtB;KACD;IACD,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AApCW,QAAA,aAAa,iBAoCxB;AAEK,MAAM,gBAAgB,GAAG,CAC/B,KAAoB,EACpB,MAAmB,EACnB,wBAAiC,EACnB,EAAE;IAEhB,IAAI,wBAAwB,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChE,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,wBAAwB,CAAC;QACvE,MAAM,aAAa,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAChD,IAAI,aAAa,EAAE;YAClB,OAAO,aAAa,CAAC;SACrB;KACD;SAAM;QACN,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrE,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE;YACnB,OAAO,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;SACxB;KACD;IACD,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAnBW,QAAA,gBAAgB,oBAmB3B;AAEK,MAAM,uBAAuB,GAAG,CACtC,gBAA+B,EAC/B,oBAAqC,EACrC,YAAyB,EACzB,MAAc,EACd,qBAAoC,EACpC,yBAA0C,EAC1C,SAAwB,EACjB,EAAE;IACT,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;QAClC,OAAO;KACP;IACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACvF,MAAM,eAAe,GAAgB,IAAA,kBAAU,EAAC,YAAY,CAAC,CAAC;IAC9D,IAAI,eAAe,EAAE;QACpB,SAAS,CAAC,SAAS,CAAC,mBAAmB,CACtC,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,CACzB,CAAC;QACF,IAAA,0BAAkB,EACjB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,MAAM,EACN,qBAAqB,EACrB,yBAAyB,EACzB,SAAS,CACT,CAAC;KACF;AACF,CAAC,CAAC;AAjCW,QAAA,uBAAuB,2BAiClC;AAEK,MAAM,kBAAkB,GAAG,CACjC,MAAmB,EACnB,KAAoB,EACpB,IAAqB,EACrB,YAA2C,EAC3C,MAAc,EACd,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACf,EAAE;IAEX,IAAI,CAAC,MAAM,EAAE;QACZ,OAAO,CAAC,CAAC;KACT;IAED,MAAM,kBAAkB,GAAG,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,EAAE,CAAC;IAIlB,MAAM,YAAY,GAAG;QACpB,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QACvB,QAAQ,EAAE,CAAC,CAAC;QACZ,MAAM,EAAE,MAAM;KAEC,CAAC;IACjB,MAAM,gBAAgB,GAAG,IAAA,oBAAY,EAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAQ3G,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE;QACnD,IAAA,kCAAkB,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;KACrE;IAED,IAAI,gBAAgB,GAAG,CAAC,EAAE;QAEzB,MAAM,SAAS,GAAG,IAAA,gCAAe,EAChC,MAAM,EACN,KAAK,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,SAAS,CACT,CAAC;KACF;IACD,IAAI,CAAC,kBAAkB,IAAI,gBAAgB,GAAG,CAAC,IAAI,QAAQ,IAAI,YAAY,IAAI,QAAQ,IAAI,YAAY,EAAE;QACxG,MAAM,CAAC,oBAAoB,GAAG,YAA2B,CAAC;QAE1D,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE;YAChD,IAAA,0BAAY,EAAC,YAA2B,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;SAC5G;KACD;IACD,MAAM,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9F,KAAK,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;IACrC,OAAO,gBAAgB,CAAC;AACzB,CAAC,CAAC;AA7DW,QAAA,kBAAkB,sBA6D7B;AAGK,MAAM,mBAAmB,GAAG,CAClC,OAAsB,EACtB,KAAoB,EACpB,IAAqB,EACrB,YAA2C,EAC3C,MAAc,EACd,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACf,EAAE;IAEX,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAA,EAAE;QACrB,OAAO,CAAC,CAAC;KACT;IAED,MAAM,iBAAiB,GAAG,EAAE,CAAC;IAC7B,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAEjG,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAI7B,MAAM,YAAY,GAAG;YACpB,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;YACvB,QAAQ,EAAE,CAAC,CAAC;YACZ,MAAM,EAAE,MAAM;SAEC,CAAC;QACjB,MAAM,gBAAgB,GAAG,IAAA,oBAAY,EAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3G,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAQzC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE;YACnD,IAAA,kCAAkB,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;SACrE;KACD;IAED,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,gBAAgB,GAAG,CAAC,EAAE;YAEzB,MAAM,SAAS,GAAG,IAAA,gCAAe,EAChC,MAAM,EACN,KAAK,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,SAAS,CACT,CAAC;SACF;QACD,IAAI,CAAC,kBAAkB,IAAI,gBAAgB,GAAG,CAAC,IAAI,QAAQ,IAAI,YAAY,IAAI,QAAQ,IAAI,YAAY,EAAE;YACxG,MAAM,CAAC,oBAAoB,GAAG,YAA2B,CAAC;YAE1D,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE;gBAChD,IAAA,0BAAY,EACX,YAA2B,EAC3B,KAAK,EACL,MAAM,EACN,UAAU,EACV,SAAS,EACT,KAAK,EACL,IAAI,EACJ,EAAE,EACF,SAAS,CACT,CAAC;aACF;SACD;QACD,MAAM,oBAAoB,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7F,KAAK,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;KACrC;IACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC;AAjFW,QAAA,mBAAmB,uBAiF9B;AAEK,MAAM,kBAAkB,GAAG,CACjC,cAA6B,EAC7B,eAA4B,EAC5B,YAAY,GAAG,KAAK,EACN,EAAE;IAChB,IAAI,wBAAU,CAAC,MAAM,EAAE;QACtB,KAAK,MAAM,aAAa,IAAI,wBAAU,CAAC,aAAa,EAAE;YACrD,IAAI,wBAAU,CAAC,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE;gBAExE,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAU,CAAC,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC9F,IAAI,CAAC,CAAC,GAAG,EAAE;oBAEV,wBAAU,CAAC,aAAa,GAAG,wBAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC;oBACtF,OAAO,GAAG,CAAC;iBACX;aAED;SACD;KACD;IAED,IAAI,iBAAyC,CAAC;IAC9C,IACC,eAAe,CAAC,MAAM,cAAgC;QACtD,eAAe,CAAC,MAAM,sBAAwC;QAC9D,eAAe,CAAC,MAAM,eAAsC;QAC5D,eAAe,CAAC,MAAM,iBAAwC,EAC7D;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7E,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;KACnF;SAAM,IACN,eAAe,CAAC,MAAM,eAAqC;QAC3D,eAAe,CAAC,MAAM,iBAAuC,EAC5D;QACD,iBAAiB,GAAG,cAAc;aAChC,MAAM,CACN,CAAC,MAAM,EAAE,EAAE,CACV,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC,MAAM,IAAI,eAAe,CAAC,QAAQ,IAAI,eAAe,CAAC,SAAS,CACjG;aACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACjC,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE;YAC9B,iBAAiB,GAAG,cAAc,CAAC;SACnC;KACD;SAAM;QACN,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,YAAY,EAAE;YAClB,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClE,iBAAiB,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC;SACnE;KACD;IAED,MAAM,cAAc,GAAG,IAAA,kBAAU,EAAC,iBAAiB,CAAC,CAAC;IAWrD,OAAO,cAAc,CAAC;AACvB,CAAC,CAAC;AA9DW,QAAA,kBAAkB,sBA8D7B;AAEK,MAAM,YAAY,GAAG,CAC3B,MAAmB,EACnB,QAAqB,EACrB,WAA0B,EAC1B,eAAgC,EAChC,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACxB,aAAa,GAAG,IAAI,EACpB,aAAa,GAAG,KAAK,EACZ,EAAE;IAEX,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC;IAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;QAC1B,OAAO,CAAC,CAAC;KACT;IAGD,IACC,MAAM,CAAC,iBAAiB,GAAG,CAAC;QAC5B,CAAC,MAAM,CAAC,MAAM,eAAgC,IAAI,MAAM,CAAC,MAAM,iBAAkC,CAAC,EACjG;QACD,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;QACzC,IAAI,SAAS,EAAE;YACd,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;YAGnG,MAAM,SAAS,GAAG;gBACjB,GAAG,MAAM;gBACT,MAAM,EAAE,QAAQ,CAAC,MAAM;aAER,CAAC;YACjB,MAAM,uBAAuB,GAAG,SAAS,CAAC,YAAY,CAAC;YACvD,MAAM,UAAU,GAAG,IAAA,oBAAY,EAC9B,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,KAAK,CACL,CAAC;YACF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAuB,EAAE;gBACpD,IAAA,kCAAkB,EAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;aACxF;YACD,IAAI,UAAU,GAAG,CAAC,EAAE;gBACnB,IAAA,gCAAe,EACd,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,UAAU,EACV,SAAS,CACT,CAAC;aACF;YACD,OAAO,UAAU,CAAC;SAClB;KACD;IAED,IAAI,MAAM,CAAC,YAAY,EAAE;QACxB,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAC1E,OAAO,CAAC,CAAC;KACT;IAED,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IACrE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC;IAG5C,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAQpF,IAAI,QAAQ,CAAC,SAAS,EAAE;QAGvB,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;KAC7B;IACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,aAAa,CAAC,IAAI,aAAa,EAAE;QAG1D,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,IAAA,yBAAc,EAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;KACnF;IAKD,MAAM,CAAC,oBAAoB,GAAG,QAAQ,CAAC;IA2BvC,OAAO,QAAQ,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC;AA3HW,QAAA,YAAY,gBA2HvB;AA+GK,MAAM,kBAAkB,GAAG,CACjC,MAAqB,EACrB,UAA2B,EAC3B,MAAqB,EACrB,UAA2B,EAC3B,SAAwB,EAExB,mBAAmB,GAAG,KAAK,EACpB,EAAE;IAKT,MAAM,CAAC,0BAA0B,EAAE,4BAA4B,EAAE,aAAa,CAAC,GAAG,IAAA,6BAAc,EAC/F,MAAM,EACN,UAAU,EACV,MAAM,EACN,UAAU,EACV,SAAS,CACT,CAAC;IACF,MAAM,CAAC,0BAA0B,EAAE,4BAA4B,EAAE,aAAa,CAAC,GAAG,IAAA,6BAAc,EAC/F,MAAM,EACN,UAAU,EACV,MAAM,EACN,UAAU,EACV,SAAS,CACT,CAAC;IAQF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;QAC7D,OAAO;KAEP;IAWD,SAAS,CAAC,SAAS,CAAC,oBAAoB,CACvC,4BAA4B,EAC5B,aAAa,EACb,MAAM,EACN,4BAA4B,EAC5B,aAAa,EACb,MAAM,CACN,CAAC;IACF,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAChC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CACjC,IAAA,2BAAmB,EAClB;QACC,GAAG,CAAC;QACJ,MAAM,EAAE,CAAC,CAAC,SAAS;QACnB,cAAc,EAAE,KAAK;QACrB,0BAA0B,EAAE,0BAA0B,CAAC,KAAK,CAAC;KAC7D,EACD,SAAS,CAAC,SAAS,CACnB,CACD,CACD,CAAC;IACF,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAChC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CACjC,IAAA,2BAAmB,EAClB;QACC,GAAG,CAAC;QACJ,MAAM,EAAE,CAAC,CAAC,SAAS;QACnB,cAAc,EAAE,KAAK;QACrB,0BAA0B,EAAE,0BAA0B,CAAC,KAAK,CAAC;KAC7D,EACD,SAAS,CAAC,SAAS,CACnB,CACD,CACD,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE;QACvC,MAAM,WAAW,GAAG,6BAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,IAAA,2BAAU,EAAC,WAAW,CAAC,EAAE;YAC5B,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE;gBAC/B,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IACD,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE;QACvC,MAAM,WAAW,GAAG,6BAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,IAAA,2BAAU,EAAC,WAAW,CAAC,EAAE;YAC5B,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE;gBAC/B,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IAED,UAAU,CAAC,UAAU,CAAC,0BAA0B;QAC/C,UAAU,CAAC,UAAU,CAAC,0BAA0B;YAChD,aAAa,CAAC,MAAM,CACnB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAmC,IAAI,CAAC,CAAC,MAAM,iBAAqC,CACnG,CAAC,MAAM,CAAC;IACV,UAAU,CAAC,UAAU,CAAC,0BAA0B;QAC/C,UAAU,CAAC,UAAU,CAAC,0BAA0B;YAChD,aAAa,CAAC,MAAM,CACnB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAmC,IAAI,CAAC,CAAC,MAAM,iBAAqC,CACnG,CAAC,MAAM,CAAC;IAEV,IAAA,yDAA6B,EAAC;QAC7B,SAAS,EAAE,SAAS;QACpB,kBAAkB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa;QACvE,gCAAgC,EAAE,UAAU,CAAC,QAAQ;YACpD,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,4BAA4B;QAC/B,oBAAoB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa;QACzE,kCAAkC,EAAE,UAAU,CAAC,QAAQ;YACtD,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,4BAA4B;KAC/B,CAAC,CAAC;IASH,IAAA,0BAAkB,EAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAGtE,IAAI,CAAC,mBAAmB,EAAE;QACzB,IAAA,0CAAsB,EAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;KAC1E;IAGD,wBAAwB,CACvB,MAAM,EACN,aAAa,EACb,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,4BAA4B,EACjF,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,4BAA4B,EACjF,UAAU,EACV,SAAS,CACT,CAAC;IAKF,MAAM;SACJ,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,cAAM,EAAC,MAAM,CAAC,CAAC;SAClC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACnB,IAAA,0CAAoB,EAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,CAAC,CAC3G,CAAC;IACH,MAAM;SACJ,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,cAAM,EAAC,MAAM,CAAC,CAAC;SAClC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACnB,IAAA,0CAAoB,EAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,CAAC,CAC3G,CAAC;IAEH,IAAA,uCAAqB,EAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC,CAAC;AAzKW,QAAA,kBAAkB,sBAyK7B;AAEF,MAAM,wBAAwB,GAAG,CAChC,MAAqB,EACrB,aAA4B,EAC5B,6BAAuC,EACvC,WAA4B,EAC5B,MAAqB,EACrB,aAA4B,EAC5B,6BAAuC,EACvC,WAA4B,EAC5B,SAAwB,EACvB,EAAE;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;IACnC,gCAAgC,CAC/B,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACxB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACtC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACtE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAClC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACxB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACtC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACtE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAClC,SAAS,CACT,CAAC;IACF,gCAAgC,CAC/B,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACzB,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACvC,CAAC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACvE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EACnC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACzB,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACvC,CAAC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACvE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EACnC,SAAS,CACT,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,gCAAgC,GAAG,CACxC,aAA4B,EAC5B,oBAAmC,EACnC,oCAA8C,EAC9C,kBAAmC,EACnC,UAAyB,EACzB,iBAAgC,EAChC,iCAA2C,EAC3C,eAAgC,EAChC,SAAwB,EACvB,EAAE;;IACH,MAAM,iBAAiB,GAAG,EAAE,CAAC;IAE7B,KAAK,MAAM,OAAO,IAAI,MAAA,kBAAkB,CAAC,QAAQ,mCAAI,EAAE,EAAE;QACxD,MAAM,gBAAgB,GAAG,6BAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,IAAA,gCAAe,EAAC,gBAAgB,CAAC,EAAE;YACtC,gBAAgB,CAAC,YAAY,CAAC,OAAO,EAAE;gBACtC,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,aAAa;gBACpB,SAAS,EAAE,eAAe;gBAC1B,UAAU,EAAE,UAAU;gBACtB,YAAY,EAAE,oBAAoB;gBAClC,4BAA4B,EAAE,oCAAoC;gBAClE,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IACD,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE;QACnC,MAAM,gBAAgB,GAAG,6BAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,IAAA,gCAAe,EAAC,gBAAgB,CAAC,EAAE;YACtC,gBAAgB,CAAC,YAAY,CAAC,MAAM,EAAE;gBACrC,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,aAAa;gBACpB,SAAS,EAAE,eAAe;gBAC1B,UAAU,EAAE,UAAU;gBACtB,YAAY,EAAE,oBAAoB;gBAClC,4BAA4B,EAAE,oCAAoC;gBAClE,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IAED,MAAM,eAAe,GAAG,IAAI,CAAC;IA0B7B,IAAA,4BAAmB,EAClB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,CAAC,EACD,UAAU,EACV,eAAe,EACf,SAAS,CACT,CAAC;AACH,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnAfterDeath, hasOnDeath } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { debugState } from '../debug-state';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { updateVenomous } from '../keywords/venomous';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { groupByFunction, pickRandom } from '../services/utils';\r\nimport { addImpliedMechanics, isFish } from '../utils';\r\nimport { applyAfterAttackEffects, applyAfterAttackTrinkets } from './after-attack';\r\nimport { onEntityDamaged } from './damage-effects';\r\nimport { rememberDeathrattles } from './deathrattle-effects';\r\nimport { orchestrateMinionDeathEffects } from './deathrattle-orchestration';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { makeMinionsDie } from './minion-death';\r\nimport { onMinionKill } from './minion-kill';\r\nimport { applyOnAttackEffects } from './on-attack';\r\nimport { applyOnBeingAttackedBuffs } from './on-being-attacked';\r\nimport { resolvePendingEffects } from './pending-effects';\r\nimport { performEntitySpawns } from './spawns';\r\nimport { applyAfterStatsUpdate } from './stats';\r\nimport { handleSummonsWhenSpace } from './summon-when-space';\r\nimport { canAttack } from './utils/entity-utils';\r\n\r\n// Only use it to simulate actual attack. To simulate damage, or something similar, use bumpInto\r\nexport const simulateAttack = (\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t\tforceTarget?: BoardEntity;\r\n\t},\r\n): BoardEntity => {\r\n\t// console.debug(\r\n\t// \t'\\nsimulating attack',\r\n\t// \tstringifySimple(attackingBoard, gameState.allCards),\r\n\t// \t'\\n',\r\n\t// \tstringifySimple(defendingBoard, gameState.allCards),\r\n\t// );\r\n\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst attackingEntity = getAttackingEntity(attackingBoard, gameState.allCards);\r\n\tif (attackingEntity) {\r\n\t\tgameState.sharedState.currentAttackerEntityId = attackingEntity.entityId;\r\n\t\t// Get the left entities now, otherwise things might break if the attacker dies and/or other\r\n\t\t// entities pop\r\n\t\tconst attackingEntityIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\tconst attackingEntitiesToTheLeft = attackingBoard.slice(0, attackingEntityIndex);\r\n\t\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\t\t// In case of Broodmother spawn, it spawns where the dead minion was, and has no influence on the\r\n\t\t// attack order\r\n\t\t// Situation this is trying to resolve by putting this right at the top of the loop:\r\n\t\t// - One scallywag attacks into another one, both die\r\n\t\t// - The first one attacks. To its left is a Harmless Bonehead with 1 HP. The scallywag attacks, and both scallys die\r\n\t\t// - The *other* sky pirate attacks first, and kills the bonehead. Two minions are spawned\r\n\t\t// - The first sy pirate attacks\r\n\t\t// - The initial loop is resolved. If this is at the end, the Harmless Bonehead is already dead, and not flagged\r\n\t\t// While having this right away, we immediately flag all minions to the left\r\n\t\tif (!isAttackingImmediately) {\r\n\t\t\t// Make sure they won't be able to attack until everyone has attacked\r\n\t\t\t// See http://replays.firestoneapp.com/?reviewId=a1b3066d-e806-44c1-ab4b-7ef9dbf9b5b9&turn=5&action=4\r\n\t\t\tattackingEntitiesToTheLeft.forEach((entity) => (entity.hasAttacked = 2));\r\n\t\t} else {\r\n\t\t\t// Change it right away so that new spawns don't trigger the \"attack immediately\" again\r\n\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t}\r\n\r\n\t\tconst numberOfAttacks = attackingEntity.windfury ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfAttacks; i++) {\r\n\t\t\t// We refresh the entity in case of windfury\r\n\t\t\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\t\t\t// We still want to flag the entity as having attacked, so that it doesn't attack again\r\n\t\t\t\t// after teammate switch in Duos\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t// Check that didn't die\r\n\t\t\tif (attackingBoard.find((entity) => entity.entityId === attackingEntity.entityId)) {\r\n\t\t\t\tconst defendingEntity: BoardEntity =\r\n\t\t\t\t\toptions?.forceTarget ?? getDefendingEntity(defendingBoard, attackingEntity);\r\n\t\t\t\t// Can happen with a single defender that has stealth\r\n\t\t\t\tif (defendingEntity && defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tdoFullAttack(\r\n\t\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t\toptions,\r\n\t\t\t\t\t);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Solves the edge case of Sky Pirate vs a stealth board\r\n\t\t\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tgameState.sharedState.currentAttackerEntityId = null;\r\n\t\tattackingEntity.hasAttacked = 1;\r\n\t}\r\n\treturn attackingEntity;\r\n};\r\n\r\nexport const doFullAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t},\r\n) => {\r\n\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\tgameState.spectator.registerAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tdefendingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoardHero,\r\n\t);\r\n\t// http://replays.firestoneapp.com/?reviewId=50576a9f-2e6a-4600-87ba-6e737ca9853e&turn=21&action=4\r\n\t// Looks like onBeingAttacked effects apply before onAttack effects\r\n\tapplyOnBeingAttackedBuffs(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker1, damageDoneByDefender: damageDoneByDefender1 } =\r\n\t\tapplyOnAttackEffects(\r\n\t\t\tattackingEntity,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker2, damageDoneByDefender: damageDoneByDefender2 } = performAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst damageDoneByAttacker = damageDoneByAttacker1 + damageDoneByAttacker2;\r\n\tconst damageDoneByDefender = damageDoneByDefender1 + damageDoneByDefender2;\r\n\r\n\t// Process this after the minions die and deathrattles are triggered/spawned\r\n\t// https://replays.firestoneapp.com/?reviewId=dd4e9dbe-abca-434a-ab94-04777cbedefe&turn=29&action=3\r\n\t// BUT: the attacking entity's afterAttack (like Macaw) needs to be processed\r\n\t// To recap:\r\n\t// - Jar o'Gems procs after the deathrattles have spawned\r\n\t// - When Monstrous Macaw procs a deathrattle, it is still on board, thus limiting the spawn room\r\n\t// So not sure what the exact timings are. It could be:\r\n\t// 1. Trigger minion's after attack\r\n\t// 2. Make minions die\r\n\t// 3. Process trinkets after attack\r\n\t// I have asked on Discord - for now I will consider a \"minion after attack\" phase and a \"trinket after attack\" phase.\r\n\t// I'm not sure about the secrets / trinkets, they will need to be adapted\r\n\t// The \"minion after attack\" phase seems to happen before the minions die:\r\n\t// https://replays.firestoneapp.com/?reviewId=ecdfab8d-e20e-4264-be4b-9cbe754118f7&turn=29&action=14\r\n\t// Here the Rally + Deathrattle minion attacks, but Deathstrider procs before it dies\r\n\tapplyAfterAttackEffects(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\r\n\tprocessMinionDeath(\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t\toptions?.skipSummonWhenSpace || isAttackingImmediately,\r\n\t);\r\n\r\n\tapplyAfterAttackTrinkets(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tattackingEntity.immuneWhenAttackCharges = Math.max(0, (attackingEntity.immuneWhenAttackCharges ?? 0) - 1);\r\n\t// if (\r\n\t// \tdefendingEntity.health > 0 &&\r\n\t// \t!defendingEntity.definitelyDead\r\n\t// \t&& (defendingEntity.cardId === CardIds.YoHoOgre_BGS_060 ||\r\n\t// \t\tdefendingEntity.cardId === CardIds.YoHoOgre_TB_BaconUps_150)\r\n\t// ) {\r\n\t// \tdefendingEntity.attackImmediately = true;\r\n\t// \tif (defendingEntity.attackImmediately) {\r\n\t// \t\tsimulateAttack(defendingBoard, defendingBoardHero, attackingBoard, attackingBoardHero, gameState);\r\n\t// \t}\r\n\t// }\r\n};\r\n\r\nconst performAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): { damageDoneByAttacker: number; damageDoneByDefender: number } => {\r\n\tlet damageDoneByAttacker = 0;\r\n\tlet damageDoneByDefender = 0;\r\n\tconst hadVenomous = attackingEntity.venomous;\r\n\r\n\tif ([CardIds.BabyKrush_BG22_001, CardIds.BabyKrush_BG22_001_G].includes(attackingEntity.cardId as CardIds)) {\r\n\t\tconst spawns = spawnEntities(\r\n\t\t\tattackingEntity.cardId === CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t? CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t: CardIds.BabyKrush_DevilsaurToken,\r\n\t\t\t1,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t\ttrue,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t\tif (spawns.length > 0) {\r\n\t\t\tconst sourceIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\t\tspawns,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tsourceIndex,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tfor (const actualSpawn of actualSpawns) {\r\n\t\t\t\tif (defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tperformAttack(\r\n\t\t\t\t\t\tactualSpawn,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\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}\r\n\t\t}\r\n\t}\r\n\r\n\t// For Prestor\r\n\tconst defenderAliveBeforeAttack = defendingEntity.health > 0 && !defendingEntity.definitelyDead;\r\n\t// Because of Bristleback Knight, which changes its divine shield status during bumpEntities\r\n\tconst attackerHadDivineShield = attackingEntity.divineShield;\r\n\tconst defenderHadDivineShield = defendingEntity.divineShield;\r\n\t// For cleave\r\n\t// We do that now so that we don't include entities that spawn on entity damaged\r\n\tconst defenderNeighbours: readonly BoardEntity[] = getNeighbours(defendingBoard, defendingEntity);\r\n\tif (defenderAliveBeforeAttack) {\r\n\t\tif (!attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\t// TODO: this bumpEntities approach doesn't work well, as it leads to code duplication\r\n\t\t\tdamageDoneByDefender += bumpEntities(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tdamageDoneByAttacker += bumpEntities(\r\n\t\t\tdefendingEntity,\r\n\t\t\tattackingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tif (defendingEntity.attack > 0 && attackerHadDivineShield && !attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (attackingEntity.attack > 0 && defenderHadDivineShield) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// This whole logic is a MEEEEESSSSSSSSSSSSSSS\r\n\t\tif (damageDoneByDefender > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdamageDoneByDefender,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (damageDoneByAttacker > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdamageDoneByAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tif (defendingEntity.health <= 0 || defendingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\ttrue,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t\tif (attackingEntity.health <= 0 || attackingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tfalse,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t}\r\n\t// Cleave\r\n\tif (attackingEntity.cleave) {\r\n\t\tfor (const neighbour of defenderNeighbours) {\r\n\t\t\tconst thisAttackDamage = bumpEntities(\r\n\t\t\t\tneighbour,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\ttrue,\r\n\t\t\t\thadVenomous,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += thisAttackDamage;\r\n\t\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t\t// cause wrong results to happen\r\n\t\t\tif (attackingEntity.attack > 0 && neighbour.divineShield) {\r\n\t\t\t\tupdateDivineShield(neighbour, defendingBoard, defendingBoardHero, attackingBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (thisAttackDamage > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\tthisAttackDamage,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tif (neighbour.health <= 0 || neighbour.definitelyDead) {\r\n\t\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tdefenderNeighbours,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tattackingEntity.attackImmediately = false;\r\n\tif (attackingEntity.enchantments.some((e) => e.cardId === CardIds.VolatileVenom_VolatileEnchantment)) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t}\r\n\treturn { damageDoneByAttacker, damageDoneByDefender };\r\n};\r\n\r\n// TODO: Could it be possible to store the index of the entity that last attacked? Probably not, because minion\r\n// spawns would mess this up? Could we update the indexes as each entity spawns / dies?\r\nconst getAttackingEntity = (attackingBoard: BoardEntity[], allCards: AllCardsService): BoardEntity => {\r\n\tlet validAttackers = attackingBoard.filter((entity) => canAttack(entity));\r\n\tif (validAttackers.length === 0) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tif (validAttackers.some((entity) => entity.attackImmediately)) {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.attackImmediately);\r\n\t} else if (validAttackers.every((e) => e.hasAttacked != null)) {\r\n\t\tattackingBoard.forEach((e) => (e.hasAttacked = undefined));\r\n\t} else {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.hasAttacked == undefined);\r\n\t}\r\n\tconst attacker = validAttackers[0];\r\n\treturn attacker;\r\n};\r\n\r\nexport const findNearestEnemies = (\r\n\tattackingBoard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tentityIndexFromRight: number,\r\n\tdefendingBoard: BoardEntity[],\r\n\tnumberOfTargets: number,\r\n\tallCards: AllCardsService,\r\n): BoardEntity[] => {\r\n\tconst result = [];\r\n\tif (defendingBoard.length > 0) {\r\n\t\t// console.debug('defending board', numberOfTargets, stringifySimple(defendingBoard, allCards));\r\n\t\tconst attackerIndex = attackingBoard.length - entityIndexFromRight - 1;\r\n\t\tconst targetIndex = attackerIndex - (attackingBoard.length - defendingBoard.length) / 2;\r\n\t\t// console.debug('indexes', attackerIndex, entityIndexFromRight, targetIndex, attackingBoard.length);\r\n\r\n\t\tfor (let i = 0; i < numberOfTargets; i++) {\r\n\t\t\tconst possibleTargets = defendingBoard\r\n\t\t\t\t.filter((e) => !e.definitelyDead && e.health > 0)\r\n\t\t\t\t.filter((e) => !result.includes(e));\r\n\t\t\t// console.debug('possibleTargets', stringifySimple(possibleTargets, allCards));\r\n\t\t\tif (!possibleTargets.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tconst targetGroups = groupByFunction((e: BoardEntity) => Math.abs(defendingBoard.indexOf(e) - targetIndex))(\r\n\t\t\t\tpossibleTargets,\r\n\t\t\t);\r\n\t\t\tconst distances = Object.keys(targetGroups)\r\n\t\t\t\t.map((k) => +k)\r\n\t\t\t\t.sort();\r\n\t\t\tconst nearestDistance = distances[0];\r\n\t\t\tif (nearestDistance != null) {\r\n\t\t\t\t// console.debug(\r\n\t\t\t\t// \t'targetGroups[nearestDistance]',\r\n\t\t\t\t// \tnearestDistance,\r\n\t\t\t\t// \tstringifySimple(targetGroups[nearestDistance], allCards),\r\n\t\t\t\t// );\r\n\t\t\t\tconst target = pickRandom(targetGroups[nearestDistance]);\r\n\t\t\t\tresult.push(target);\r\n\t\t\t}\r\n\t\t\t// console.debug('\\n');\r\n\t\t}\r\n\t}\r\n\treturn result.filter((e) => !!e);\r\n};\r\n\r\nexport const getNeighbours = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n\talwaysIncludeBoth = false,\r\n): readonly BoardEntity[] => {\r\n\tconst neighbours = [];\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\tneighbours.push(leftNeighbour);\r\n\t\t}\r\n\r\n\t\t// If the deadEntityIndexFromRight === 0 (right-most minion), no neighbour will be found\r\n\t\tconst rightNeighbourIndex = board.length - 1 - (deadEntityIndexFromRight - 1);\r\n\t\tconst rightNeighbour = board[rightNeighbourIndex];\r\n\t\tif (rightNeighbour) {\r\n\t\t\tneighbours.push(rightNeighbour);\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\tneighbours.push(board[index - 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t\t// neighbours.push(entity);\r\n\t\tif (index + 1 < board.length) {\r\n\t\t\tneighbours.push(board[index + 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t}\r\n\treturn neighbours;\r\n};\r\n\r\nexport const getLeftNeighbour = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n): BoardEntity => {\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\treturn leftNeighbour;\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\treturn board[index - 1];\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const dealDamageToRandomEnemy = (\r\n\tboardToBeDamaged: BoardEntity[],\r\n\tboardToBeDamagedHero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity,\r\n\tdamage: number,\r\n\tboardWithAttackOrigin: BoardEntity[],\r\n\tboardWithAttackOriginHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (boardToBeDamaged.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\tconst validTargets = boardToBeDamaged.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst defendingEntity: BoardEntity = pickRandom(validTargets);\r\n\tif (defendingEntity) {\r\n\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\tdamageSource,\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t);\r\n\t\tdealDamageToMinion(\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tdamageSource,\r\n\t\t\tdamage,\r\n\t\t\tboardWithAttackOrigin,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n};\r\n\r\nexport const dealDamageToMinion = (\r\n\ttarget: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!target) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst isDeadBeforeDamage = target.definitelyDead || target.health <= 0;\r\n\tconst spawns = [];\r\n\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t// without it\r\n\tconst fakeAttacker = {\r\n\t\t...(damageSource || {}),\r\n\t\tentityId: -1,\r\n\t\tattack: damage,\r\n\t\t// attacking: true,\r\n\t} as BoardEntity;\r\n\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\r\n\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t// cause wrong results to happen\r\n\t// TODO: why isn't it done in bumpEntities?\r\n\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t// the divine shield once both bumps are done\r\n\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t}\r\n\r\n\tif (actualDamageDone > 0) {\r\n\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\ttarget,\r\n\t\t\tboard,\r\n\t\t\thero,\r\n\t\t\totherBoard,\r\n\t\t\totherHero,\r\n\t\t\tdamageSource,\r\n\t\t\tactualDamageDone,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\r\n\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\tonMinionKill(damageSource as BoardEntity, false, target, otherBoard, otherHero, board, hero, [], gameState);\r\n\t\t}\r\n\t}\r\n\tconst defendingEntityIndex = board.findIndex((entity) => entity.entityId === target.entityId);\r\n\tboard[defendingEntityIndex] = target;\r\n\treturn actualDamageDone;\r\n};\r\n\r\n// Because the \"onEntityDamaged\" effect is only called once all the minions are damaged\r\nexport const dealDamageToMinions = (\r\n\ttargets: BoardEntity[],\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!targets?.length) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst actualDamagesDone = [];\r\n\tconst areDeadBeforeDamage = targets.map((target) => target.definitelyDead || target.health <= 0);\r\n\r\n\tfor (const target of targets) {\r\n\t\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t\t// without it\r\n\t\tconst fakeAttacker = {\r\n\t\t\t...(damageSource || {}),\r\n\t\t\tentityId: -1,\r\n\t\t\tattack: damage,\r\n\t\t\t// attacking: true,\r\n\t\t} as BoardEntity;\r\n\t\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\t\tactualDamagesDone.push(actualDamageDone);\r\n\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// TODO: why isn't it done in bumpEntities?\r\n\t\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t\t// the divine shield once both bumps are done\r\n\t\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\t\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t\t}\r\n\t}\r\n\r\n\tconst spawns = [];\r\n\tfor (let i = 0; i < targets.length; i++) {\r\n\t\tconst target = targets[i];\r\n\t\tconst actualDamageDone = actualDamagesDone[i];\r\n\t\tconst isDeadBeforeDamage = areDeadBeforeDamage[i];\r\n\t\tif (actualDamageDone > 0) {\r\n\t\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\t\ttarget,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tdamageSource,\r\n\t\t\t\tactualDamageDone,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\r\n\t\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\t\tonMinionKill(\r\n\t\t\t\t\tdamageSource as BoardEntity,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tboard,\r\n\t\t\t\t\thero,\r\n\t\t\t\t\t[],\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\tconst defendingEntityIndex = board.map((entity) => entity.entityId).indexOf(target.entityId);\r\n\t\tboard[defendingEntityIndex] = target;\r\n\t}\r\n\treturn actualDamagesDone.reduce((a, b) => a + b, 0);\r\n};\r\n\r\nexport const getDefendingEntity = (\r\n\tdefendingBoard: BoardEntity[],\r\n\tattackingEntity: BoardEntity,\r\n\tignoreTaunts = false,\r\n): BoardEntity => {\r\n\tif (debugState.active) {\r\n\t\tfor (const forcedFaceOff of debugState.forcedFaceOff) {\r\n\t\t\tif (debugState.isCorrectEntity(forcedFaceOff.attacker, attackingEntity)) {\r\n\t\t\t\t// if (attackingEntity.entityId === forcedFaceOff.attacker.entityId) {\r\n\t\t\t\tconst def = defendingBoard.find((e) => debugState.isCorrectEntity(forcedFaceOff.defender, e));\r\n\t\t\t\tif (!!def) {\r\n\t\t\t\t\t// Remove the face-off\r\n\t\t\t\t\tdebugState.forcedFaceOff = debugState.forcedFaceOff.filter((f) => f != forcedFaceOff);\r\n\t\t\t\t\treturn def;\r\n\t\t\t\t}\r\n\t\t\t\t// }\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tlet possibleDefenders: readonly BoardEntity[];\r\n\tif (\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_BGS_022 ||\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_TB_BaconUps_091 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845_G\r\n\t) {\r\n\t\tconst minAttack = Math.min(...defendingBoard.map((entity) => entity.attack));\r\n\t\tpossibleDefenders = defendingBoard.filter((entity) => entity.attack === minAttack);\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921 ||\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921_G\r\n\t) {\r\n\t\tpossibleDefenders = defendingBoard\r\n\t\t\t.filter(\r\n\t\t\t\t(entity) =>\r\n\t\t\t\t\tentity.health <= attackingEntity.attack || attackingEntity.venomous || attackingEntity.poisonous,\r\n\t\t\t)\r\n\t\t\t.filter((e) => !e.divineShield);\r\n\t\tif (!possibleDefenders.length) {\r\n\t\t\tpossibleDefenders = defendingBoard;\r\n\t\t}\r\n\t} else {\r\n\t\tpossibleDefenders = defendingBoard.filter((e) => !e.stealth);\r\n\t\tif (!ignoreTaunts) {\r\n\t\t\tconst taunts = possibleDefenders.filter((entity) => entity.taunt);\r\n\t\t\tpossibleDefenders = taunts.length > 0 ? taunts : possibleDefenders;\r\n\t\t}\r\n\t}\r\n\r\n\tconst chosenDefender = pickRandom(possibleDefenders);\r\n\t// if (chosenDefender?.taunt) {\r\n\t// \tconst elistras = defendingBoard.filter(\r\n\t// \t\t(entity) =>\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_BGS_205 ||\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_TB_BaconUps_306,\r\n\t// \t);\r\n\t// \tif (elistras.length > 0) {\r\n\t// \t\tchosenDefender = elistras[Math.floor(Math.random() * elistras.length)];\r\n\t// \t}\r\n\t// }\r\n\treturn chosenDefender;\r\n};\r\n\r\nexport const bumpEntities = (\r\n\tentity: BoardEntity,\r\n\tbumpInto: BoardEntity,\r\n\tentityBoard: BoardEntity[],\r\n\tentityBoardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tapplyVenomous = true,\r\n\tforceVenomous = false,\r\n): number => {\r\n\t// No attack has no impact\r\n\tconst debug = bumpInto.cardId === 'BG26_888';\r\n\tif (bumpInto.attack === 0) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// Matador effect has priority\r\n\tif (\r\n\t\tentity.abiityChargesLeft > 0 &&\r\n\t\t(entity.cardId === CardIds.MadMatador_BG28_404 || entity.cardId === CardIds.MadMatador_BG28_404_G)\r\n\t) {\r\n\t\tentity.abiityChargesLeft--;\r\n\t\tconst newTarget = pickRandom(otherBoard);\r\n\t\tif (newTarget) {\r\n\t\t\tgameState.spectator.registerPowerTarget(entity, newTarget, otherBoard, entityBoardHero, otherHero);\r\n\t\t\t// TODO: here the MadMatador is the source of the damage, not the initial attacker\r\n\t\t\t// Not sure exactly what the impact would be, as there is no counter\r\n\t\t\tconst newSource = {\r\n\t\t\t\t...entity,\r\n\t\t\t\tattack: bumpInto.attack,\r\n\t\t\t\t// attacking: true,\r\n\t\t\t} as BoardEntity;\r\n\t\t\tconst defenderHadDivineShield = newTarget.divineShield;\r\n\t\t\tconst damageDone = bumpEntities(\r\n\t\t\t\tnewTarget,\r\n\t\t\t\tnewSource,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tentityBoard,\r\n\t\t\t\tentityBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\tfalse,\r\n\t\t\t);\r\n\t\t\tif (newSource.attack > 0 && defenderHadDivineShield) {\r\n\t\t\t\tupdateDivineShield(newTarget, otherBoard, otherHero, entityBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (damageDone > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tnewTarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tentityBoard,\r\n\t\t\t\t\tentityBoardHero,\r\n\t\t\t\t\tnewSource,\r\n\t\t\t\t\tdamageDone,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\treturn damageDone;\r\n\t\t}\r\n\t}\r\n\r\n\tif (entity.divineShield) {\r\n\t\tgameState.spectator.registerDamageDealt(bumpInto, entity, 0, entityBoard);\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst damageDealt = (entity.damageMultiplier || 1) * bumpInto.attack;\r\n\tentity.health = entity.health - damageDealt;\r\n\t// FIXME: This will likely be incorrect in terms of timings, e.g. if the entity ends up\r\n\t// surviving following a buff like Spawn.\r\n\tgameState.spectator.registerDamageDealt(bumpInto, entity, damageDealt, entityBoard);\r\n\r\n\t// if (entity.cardId === CardIds.Bubblette_BG_TID_713 && bumpInto.attack === 1) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// } else if (entity.cardId === CardIds.Bubblette_BG_TID_713_G && bumpInto.attack === 2) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// }\r\n\t// Do it last, so that other effects are still processed\r\n\tif (bumpInto.poisonous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t}\r\n\tif ((bumpInto.venomous || forceVenomous) && applyVenomous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t\tupdateVenomous(bumpInto, false, otherBoard, otherHero, entityBoardHero, gameState);\r\n\t}\r\n\t// Ideally we should do the Reckoning stuff here. However, at this point we only have half the damage\r\n\t// information, so it is possible that the entity deals more than 3 (which should trigger Reckoning)\r\n\t// but dies during the exchange (and Reckoning doesn't trigger then)\r\n\r\n\tentity.lastAffectedByEntity = bumpInto;\r\n\t// if (entity.frenzyChargesLeft > 0 && entity.health > 0 && !entity.definitelyDead) {\r\n\t// \tapplyFrenzy(entity, entityBoard, entityBoardHero, gameState);\r\n\t// \tentity.frenzyChargesLeft--;\r\n\t// }\r\n\r\n\t// We spawn them here, because it says \"whenever\", and so happens right away\r\n\t// FIXME: there could be a bug here, if a Cleave attacks several IGB at the same time. The current\r\n\t// implementation could spawn minions above the max board size. Fringe case though, so leaving it\r\n\t// like this for now\r\n\t// const entitySpawns = getWheneverEntitySpawns(\r\n\t// \tentity,\r\n\t// \tentityBoard,\r\n\t// \tentityBoardHero,\r\n\t// \totherBoard,\r\n\t// \totherHero,\r\n\t// \tgameState.allCards,\r\n\t// \tgameState.cardsData,\r\n\t// \tgameState.sharedState,\r\n\t// \tgameState.spectator,\r\n\t// );\r\n\t// if (!!entitySpawns?.length) {\r\n\t// \t// Spawn to the right\r\n\t// \tconst index = entityBoard.map((e) => e.entityId).indexOf(entity.entityId) + 1;\r\n\t// \taddMinionsToBoard(entityBoard, entityBoardHero, otherHero, index, entitySpawns, gameState);\r\n\t// \tgameState.spectator.registerMinionsSpawn(entity, entityBoard, entitySpawns);\r\n\t// }\r\n\treturn bumpInto.attack;\r\n};\r\n\r\n// const getWheneverEntitySpawns = (\r\n// \tentity: BoardEntity,\r\n// \tentityBoard: BoardEntity[],\r\n// \tentityBoardHero: BgsPlayerEntity,\r\n// \totherBoard: BoardEntity[],\r\n// \totherHero: BgsPlayerEntity,\r\n// \tallCards: AllCardsService,\r\n// \tcardsData: CardsData,\r\n// \tsharedState: SharedState,\r\n// \tspectator: Spectator,\r\n// ): readonly BoardEntity[] => {\r\n// \tif (entityBoard.length === 7) {\r\n// \t\treturn null;\r\n// \t}\r\n\r\n// \tif (entity.cardId === CardIds.ImpGangBoss_BRM_006) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_BRM_006t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpGangBoss_TB_BaconUps_030) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_TB_BaconUps_030t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpMama_BGS_044) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.ImpMama_TB_BaconUps_116) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t2,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_BOT_218) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_BOT_218t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_TB_BaconUps_041) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_TB_BaconUps_041t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t}\r\n// \treturn null;\r\n// };\r\n\r\nexport const processMinionDeath = (\r\n\tboard1: BoardEntity[],\r\n\tboard1Hero: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tboard2Hero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\t// When we're in an \"attack immediately\" phase, we wait until we're out of the phase to summon minions\r\n\tskipSummonWhenSpace = false,\r\n): void => {\r\n\t// const debug = board1.some((e) => e.health <= 0) || board2.some((e) => e.health <= 0);\r\n\t// debug && console.debug('\\nprocessing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\tconst [deadMinionIndexesFromLeft1, deadMinionIndexesFromRights1, deadEntities1] = makeMinionsDie(\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\tconst [deadMinionIndexesFromLeft2, deadMinionIndexesFromRights2, deadEntities2] = makeMinionsDie(\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tgameState,\r\n\t);\r\n\t// debug && console.debug('after processing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\t// debug && console.debug(deadMinionIndexesFromRights1);\r\n\t// debug && console.debug(deadMinionIndexesFromRights2);\r\n\t// console.debug('dead entities', stringifySimple(deadEntities1, allCards), stringifySimple(deadEntities2, allCards));\r\n\t// No death to process, we can return\r\n\tif (deadEntities1.length === 0 && deadEntities2.length === 0) {\r\n\t\treturn;\r\n\t\t// return [board1, board2];\r\n\t}\r\n\r\n\t// Remember them right away, so that subsequent deaths do not break the order\r\n\t// TODO: move this to the deathrattle-orchestration?\r\n\t// If the fish dies (from Scallywag for instance), it doesn't remember the deathrattle\r\n\t// console.debug(\r\n\t// \t'\\n\\ndeadEntities',\r\n\t// \tstringifySimple(deadEntities1, gameState.allCards),\r\n\t// \tstringifySimple(deadEntities2, gameState.allCards),\r\n\t// );\r\n\r\n\tgameState.spectator.registerDeadEntities(\r\n\t\tdeadMinionIndexesFromRights1,\r\n\t\tdeadEntities1,\r\n\t\tboard1,\r\n\t\tdeadMinionIndexesFromRights2,\r\n\t\tdeadEntities2,\r\n\t\tboard2,\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities1.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft1[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities2.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft2[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\r\n\tfor (const deadEntity of deadEntities1) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board1Hero,\r\n\t\t\t\tboard: board1,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const deadEntity of deadEntities2) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board2Hero,\r\n\t\t\t\tboard: board2,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tboard1Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard1Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities1.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\tboard2Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard2Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities2.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\r\n\torchestrateMinionDeathEffects({\r\n\t\tgameState: gameState,\r\n\t\tplayerDeadEntities: board1Hero.friendly ? deadEntities1 : deadEntities2,\r\n\t\tplayerDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights1\r\n\t\t\t: deadMinionIndexesFromRights2,\r\n\t\topponentDeadEntities: board1Hero.friendly ? deadEntities2 : deadEntities1,\r\n\t\topponentDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights2\r\n\t\t\t: deadMinionIndexesFromRights1,\r\n\t});\r\n\r\n\t// Make sure we only return when there are no more deaths to process\r\n\t// Make sure to do this right before the end of the process\r\n\t// FIXME: this will propagate the killer between rounds, which is incorrect. For instance,\r\n\t// if a dragon kills a Ghoul, then the Ghoul's deathrattle kills a Kaboom, the killer should\r\n\t// now be the ghoul. Then if the Kaboom kills someone, the killer should again change. You could\r\n\t// also have multiple killers, which is not taken into account here.\r\n\t// The current assumption is that it's a suffienctly fringe case to not matter too much\r\n\tprocessMinionDeath(board1, board1Hero, board2, board2Hero, gameState);\r\n\r\n\t// Not sure about the timing here, but I have bothered Mitchell quite a lot already recently :)\r\n\tif (!skipSummonWhenSpace) {\r\n\t\thandleSummonsWhenSpace(board1, board1Hero, board2, board2Hero, gameState);\r\n\t}\r\n\r\n\t// Apply \"after minion death\" effects\r\n\thandleAfterMinionsDeaths(\r\n\t\tboard1,\r\n\t\tdeadEntities1,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights1 : deadMinionIndexesFromRights2,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tdeadEntities2,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights2 : deadMinionIndexesFromRights1,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\r\n\t// Only when all deathrattles have resolved\r\n\t// 2025-12-20: https://replays.firestoneapp.com/?reviewId=7d8f9af4-b484-4256-976b-ff9df8847b50&turn=5&action=0\r\n\t// Confirmed by dev that the fish doesn't get the deathrattle in this case\r\n\tboard1\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities1, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\tboard2\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities2, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\r\n\tresolvePendingEffects(board1, board1Hero, board2, board2Hero, gameState);\r\n};\r\n\r\nconst handleAfterMinionsDeaths = (\r\n\tboard1: BoardEntity[],\r\n\tdeadEntities1: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight1: number[],\r\n\theroEntity1: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tdeadEntities2: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight2: number[],\r\n\theroEntity2: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst random = Math.random() > 0.5;\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\trandom ? board1 : board2,\r\n\t\trandom ? deadEntities1 : deadEntities2,\r\n\t\trandom ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\trandom ? heroEntity1 : heroEntity2,\r\n\t\trandom ? board2 : board1,\r\n\t\trandom ? deadEntities2 : deadEntities1,\r\n\t\trandom ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\trandom ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\t!random ? board1 : board2,\r\n\t\t!random ? deadEntities1 : deadEntities2,\r\n\t\t!random ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\t!random ? heroEntity1 : heroEntity2,\r\n\t\t!random ? board2 : board1,\r\n\t\t!random ? deadEntities2 : deadEntities1,\r\n\t\t!random ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\t!random ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nconst handleAfterMinionsDeathsForBoard = (\r\n\tfriendlyBoard: BoardEntity[],\r\n\tfriendlyDeadEntities: BoardEntity[],\r\n\tfriendlyDeadEntitiesIndexesFromRight: number[],\r\n\tfriendlyHeroEntity: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherDeadEntities: BoardEntity[],\r\n\totherDeadEntitiesIndexesFromRight: number[],\r\n\totherHeroEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities = [];\r\n\r\n\tfor (const trinket of friendlyHeroEntity.trinkets ?? []) {\r\n\t\tconst onAfterDeathImpl = cardMappings[trinket.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(trinket, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const entity of friendlyBoard) {\r\n\t\tconst onAfterDeathImpl = cardMappings[entity.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(entity, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tconst secretTriggered = null;\r\n\t// if (\r\n\t// \t(secretTriggered = friendlyHeroEntity.secrets?.find(\r\n\t// \t\t(secret) => !secret.triggered && secret?.cardId === CardIds.MagicBlackSoulstone,\r\n\t// \t)) != null\r\n\t// ) {\r\n\t// \tif (friendlyBoard.length === 0) {\r\n\t// \t\tsecretTriggered.triggered = true;\r\n\t// \t\tfor (let i = 0; i < 2; i++) {\r\n\t// \t\t\tconst toSummon = pickRandom(gameState.cardsData.demonSpawns);\r\n\t// \t\t\tcandidateEntities.push(\r\n\t// \t\t\t\t...spawnEntities(\r\n\t// \t\t\t\t\ttoSummon,\r\n\t// \t\t\t\t\t1,\r\n\t// \t\t\t\t\tfriendlyBoard,\r\n\t// \t\t\t\t\tfriendlyHeroEntity,\r\n\t// \t\t\t\t\totherBoard,\r\n\t// \t\t\t\t\totherHeroEntity,\r\n\t// \t\t\t\t\tgameState,\r\n\t// \t\t\t\t\tfriendlyHeroEntity.friendly,\r\n\t// \t\t\t\t\tfalse,\r\n\t// \t\t\t\t),\r\n\t// \t\t\t);\r\n\t// \t\t}\r\n\t// \t}\r\n\t// }\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tfriendlyBoard,\r\n\t\tfriendlyHeroEntity,\r\n\t\tsecretTriggered,\r\n\t\t0,\r\n\t\totherBoard,\r\n\t\totherHeroEntity,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport interface OnDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnAfterDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly deadEntities: BoardEntity[];\r\n\treadonly deadEntitiesIndexesFromRight: number[];\r\n\treadonly gameState: FullGameState;\r\n}\r\n\r\n/** A friendly board minion just died (during death processing). Implementations filter (e.g. Taunt) as needed. */\r\nexport interface OnAfterFriendlyMinionDeathInput {\r\n\treadonly deadEntity: BoardEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly boardBeforeProcs: BoardEntity[];\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnMinionKilledInput {\r\n\treadonly killer: BoardEntity;\r\n\treadonly killerIsAttacking: boolean;\r\n\treadonly minionKilled: BoardEntity;\r\n\treadonly attackingHero: BgsPlayerEntity;\r\n\treadonly attackingBoard: BoardEntity[];\r\n\treadonly defendingHero: BgsPlayerEntity;\r\n\treadonly defendingBoard: BoardEntity[];\r\n\treadonly defenderNeighbours: readonly BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n\treadonly playerIsFriendly: boolean;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"attack.js","sourceRoot":"","sources":["../../src/simulation/attack.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 { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnAfterDeath, hasOnDeath } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { debugState } from '../debug-state';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { updateVenomous } from '../keywords/venomous';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { groupByFunction, pickRandom } from '../services/utils';\r\nimport { addImpliedMechanics, isBoardEntity, isFish } from '../utils';\r\nimport { applyAfterAttackEffects, applyAfterAttackTrinkets } from './after-attack';\r\nimport { onEntityDamaged } from './damage-effects';\r\nimport { rememberDeathrattles } from './deathrattle-effects';\r\nimport { orchestrateMinionDeathEffects } from './deathrattle-orchestration';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { makeMinionsDie } from './minion-death';\r\nimport { onMinionKill } from './minion-kill';\r\nimport { applyOnAttackEffects } from './on-attack';\r\nimport { applyOnBeingAttackedBuffs } from './on-being-attacked';\r\nimport { resolvePendingEffects } from './pending-effects';\r\nimport { performEntitySpawns } from './spawns';\r\nimport { applyAfterStatsUpdate } from './stats';\r\nimport { handleSummonsWhenSpace } from './summon-when-space';\r\nimport { canAttack } from './utils/entity-utils';\r\n\r\n// Only use it to simulate actual attack. To simulate damage, or something similar, use bumpInto\r\nexport const simulateAttack = (\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t\tforceTarget?: BoardEntity;\r\n\t},\r\n): BoardEntity => {\r\n\t// console.debug(\r\n\t// \t'\\nsimulating attack',\r\n\t// \tstringifySimple(attackingBoard, gameState.allCards),\r\n\t// \t'\\n',\r\n\t// \tstringifySimple(defendingBoard, gameState.allCards),\r\n\t// );\r\n\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst attackingEntity = getAttackingEntity(attackingBoard, gameState.allCards);\r\n\tif (attackingEntity) {\r\n\t\tgameState.sharedState.currentAttackerEntityId = attackingEntity.entityId;\r\n\t\t// Get the left entities now, otherwise things might break if the attacker dies and/or other\r\n\t\t// entities pop\r\n\t\tconst attackingEntityIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\tconst attackingEntitiesToTheLeft = attackingBoard.slice(0, attackingEntityIndex);\r\n\t\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\t\t// In case of Broodmother spawn, it spawns where the dead minion was, and has no influence on the\r\n\t\t// attack order\r\n\t\t// Situation this is trying to resolve by putting this right at the top of the loop:\r\n\t\t// - One scallywag attacks into another one, both die\r\n\t\t// - The first one attacks. To its left is a Harmless Bonehead with 1 HP. The scallywag attacks, and both scallys die\r\n\t\t// - The *other* sky pirate attacks first, and kills the bonehead. Two minions are spawned\r\n\t\t// - The first sy pirate attacks\r\n\t\t// - The initial loop is resolved. If this is at the end, the Harmless Bonehead is already dead, and not flagged\r\n\t\t// While having this right away, we immediately flag all minions to the left\r\n\t\tif (!isAttackingImmediately) {\r\n\t\t\t// Make sure they won't be able to attack until everyone has attacked\r\n\t\t\t// See http://replays.firestoneapp.com/?reviewId=a1b3066d-e806-44c1-ab4b-7ef9dbf9b5b9&turn=5&action=4\r\n\t\t\tattackingEntitiesToTheLeft.forEach((entity) => (entity.hasAttacked = 2));\r\n\t\t} else {\r\n\t\t\t// Change it right away so that new spawns don't trigger the \"attack immediately\" again\r\n\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t}\r\n\r\n\t\tconst numberOfAttacks = attackingEntity.windfury ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfAttacks; i++) {\r\n\t\t\t// We refresh the entity in case of windfury\r\n\t\t\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\t\t\t// We still want to flag the entity as having attacked, so that it doesn't attack again\r\n\t\t\t\t// after teammate switch in Duos\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t// Check that didn't die\r\n\t\t\tif (attackingBoard.find((entity) => entity.entityId === attackingEntity.entityId)) {\r\n\t\t\t\tconst defendingEntity: BoardEntity =\r\n\t\t\t\t\toptions?.forceTarget ?? getDefendingEntity(defendingBoard, attackingEntity);\r\n\t\t\t\t// Can happen with a single defender that has stealth\r\n\t\t\t\tif (defendingEntity && defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tdoFullAttack(\r\n\t\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t\toptions,\r\n\t\t\t\t\t);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Solves the edge case of Sky Pirate vs a stealth board\r\n\t\t\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tgameState.sharedState.currentAttackerEntityId = null;\r\n\t\tattackingEntity.hasAttacked = 1;\r\n\t}\r\n\treturn attackingEntity;\r\n};\r\n\r\nexport const doFullAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t},\r\n) => {\r\n\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\tgameState.spectator.registerAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tdefendingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoardHero,\r\n\t);\r\n\t// http://replays.firestoneapp.com/?reviewId=50576a9f-2e6a-4600-87ba-6e737ca9853e&turn=21&action=4\r\n\t// Looks like onBeingAttacked effects apply before onAttack effects\r\n\tapplyOnBeingAttackedBuffs(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker1, damageDoneByDefender: damageDoneByDefender1 } =\r\n\t\tapplyOnAttackEffects(\r\n\t\t\tattackingEntity,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker2, damageDoneByDefender: damageDoneByDefender2 } = performAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst damageDoneByAttacker = damageDoneByAttacker1 + damageDoneByAttacker2;\r\n\tconst damageDoneByDefender = damageDoneByDefender1 + damageDoneByDefender2;\r\n\r\n\t// Process this after the minions die and deathrattles are triggered/spawned\r\n\t// https://replays.firestoneapp.com/?reviewId=dd4e9dbe-abca-434a-ab94-04777cbedefe&turn=29&action=3\r\n\t// BUT: the attacking entity's afterAttack (like Macaw) needs to be processed\r\n\t// To recap:\r\n\t// - Jar o'Gems procs after the deathrattles have spawned\r\n\t// - When Monstrous Macaw procs a deathrattle, it is still on board, thus limiting the spawn room\r\n\t// So not sure what the exact timings are. It could be:\r\n\t// 1. Trigger minion's after attack\r\n\t// 2. Make minions die\r\n\t// 3. Process trinkets after attack\r\n\t// I have asked on Discord - for now I will consider a \"minion after attack\" phase and a \"trinket after attack\" phase.\r\n\t// I'm not sure about the secrets / trinkets, they will need to be adapted\r\n\t// The \"minion after attack\" phase seems to happen before the minions die:\r\n\t// https://replays.firestoneapp.com/?reviewId=ecdfab8d-e20e-4264-be4b-9cbe754118f7&turn=29&action=14\r\n\t// Here the Rally + Deathrattle minion attacks, but Deathstrider procs before it dies\r\n\tapplyAfterAttackEffects(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\r\n\tprocessMinionDeath(\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t\toptions?.skipSummonWhenSpace || isAttackingImmediately,\r\n\t);\r\n\r\n\tapplyAfterAttackTrinkets(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tattackingEntity.immuneWhenAttackCharges = Math.max(0, (attackingEntity.immuneWhenAttackCharges ?? 0) - 1);\r\n\t// if (\r\n\t// \tdefendingEntity.health > 0 &&\r\n\t// \t!defendingEntity.definitelyDead\r\n\t// \t&& (defendingEntity.cardId === CardIds.YoHoOgre_BGS_060 ||\r\n\t// \t\tdefendingEntity.cardId === CardIds.YoHoOgre_TB_BaconUps_150)\r\n\t// ) {\r\n\t// \tdefendingEntity.attackImmediately = true;\r\n\t// \tif (defendingEntity.attackImmediately) {\r\n\t// \t\tsimulateAttack(defendingBoard, defendingBoardHero, attackingBoard, attackingBoardHero, gameState);\r\n\t// \t}\r\n\t// }\r\n};\r\n\r\nconst performAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): { damageDoneByAttacker: number; damageDoneByDefender: number } => {\r\n\tlet damageDoneByAttacker = 0;\r\n\tlet damageDoneByDefender = 0;\r\n\tconst hadVenomous = attackingEntity.venomous;\r\n\r\n\tif ([CardIds.BabyKrush_BG22_001, CardIds.BabyKrush_BG22_001_G].includes(attackingEntity.cardId as CardIds)) {\r\n\t\tconst spawns = spawnEntities(\r\n\t\t\tattackingEntity.cardId === CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t? CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t: CardIds.BabyKrush_DevilsaurToken,\r\n\t\t\t1,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t\ttrue,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t\tif (spawns.length > 0) {\r\n\t\t\tconst sourceIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\t\tspawns,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tsourceIndex,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tfor (const actualSpawn of actualSpawns) {\r\n\t\t\t\tif (defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tperformAttack(\r\n\t\t\t\t\t\tactualSpawn,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\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}\r\n\t\t}\r\n\t}\r\n\r\n\t// For Prestor\r\n\tconst defenderAliveBeforeAttack = defendingEntity.health > 0 && !defendingEntity.definitelyDead;\r\n\t// Because of Bristleback Knight, which changes its divine shield status during bumpEntities\r\n\tconst attackerHadDivineShield = attackingEntity.divineShield;\r\n\tconst defenderHadDivineShield = defendingEntity.divineShield;\r\n\t// For cleave\r\n\t// We do that now so that we don't include entities that spawn on entity damaged\r\n\tconst defenderNeighbours: readonly BoardEntity[] = getNeighbours(defendingBoard, defendingEntity);\r\n\tif (defenderAliveBeforeAttack) {\r\n\t\tif (!attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\t// TODO: this bumpEntities approach doesn't work well, as it leads to code duplication\r\n\t\t\tdamageDoneByDefender += bumpEntities(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tdamageDoneByAttacker += bumpEntities(\r\n\t\t\tdefendingEntity,\r\n\t\t\tattackingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tif (defendingEntity.attack > 0 && attackerHadDivineShield && !attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (attackingEntity.attack > 0 && defenderHadDivineShield) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// This whole logic is a MEEEEESSSSSSSSSSSSSSS\r\n\t\tif (damageDoneByDefender > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdamageDoneByDefender,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (damageDoneByAttacker > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdamageDoneByAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tif (defendingEntity.health <= 0 || defendingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\ttrue,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t\tif (attackingEntity.health <= 0 || attackingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tfalse,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t}\r\n\t// Cleave\r\n\tif (attackingEntity.cleave) {\r\n\t\tfor (const neighbour of defenderNeighbours) {\r\n\t\t\tconst thisAttackDamage = bumpEntities(\r\n\t\t\t\tneighbour,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\ttrue,\r\n\t\t\t\thadVenomous,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += thisAttackDamage;\r\n\t\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t\t// cause wrong results to happen\r\n\t\t\tif (attackingEntity.attack > 0 && neighbour.divineShield) {\r\n\t\t\t\tupdateDivineShield(neighbour, defendingBoard, defendingBoardHero, attackingBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (thisAttackDamage > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\tthisAttackDamage,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tif (neighbour.health <= 0 || neighbour.definitelyDead) {\r\n\t\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tdefenderNeighbours,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tattackingEntity.attackImmediately = false;\r\n\tif (attackingEntity.enchantments.some((e) => e.cardId === CardIds.VolatileVenom_VolatileEnchantment)) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t}\r\n\treturn { damageDoneByAttacker, damageDoneByDefender };\r\n};\r\n\r\n// TODO: Could it be possible to store the index of the entity that last attacked? Probably not, because minion\r\n// spawns would mess this up? Could we update the indexes as each entity spawns / dies?\r\nconst getAttackingEntity = (attackingBoard: BoardEntity[], allCards: AllCardsService): BoardEntity => {\r\n\tlet validAttackers = attackingBoard.filter((entity) => canAttack(entity));\r\n\tif (validAttackers.length === 0) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tif (validAttackers.some((entity) => entity.attackImmediately)) {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.attackImmediately);\r\n\t} else if (validAttackers.every((e) => e.hasAttacked != null)) {\r\n\t\tattackingBoard.forEach((e) => (e.hasAttacked = undefined));\r\n\t} else {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.hasAttacked == undefined);\r\n\t}\r\n\tconst attacker = validAttackers[0];\r\n\treturn attacker;\r\n};\r\n\r\nexport const findNearestEnemies = (\r\n\tattackingBoard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tentityIndexFromRight: number,\r\n\tdefendingBoard: BoardEntity[],\r\n\tnumberOfTargets: number,\r\n\tallCards: AllCardsService,\r\n): BoardEntity[] => {\r\n\tconst result = [];\r\n\tif (defendingBoard.length > 0) {\r\n\t\t// console.debug('defending board', numberOfTargets, stringifySimple(defendingBoard, allCards));\r\n\t\tconst attackerIndex = attackingBoard.length - entityIndexFromRight - 1;\r\n\t\tconst targetIndex = attackerIndex - (attackingBoard.length - defendingBoard.length) / 2;\r\n\t\t// console.debug('indexes', attackerIndex, entityIndexFromRight, targetIndex, attackingBoard.length);\r\n\r\n\t\tfor (let i = 0; i < numberOfTargets; i++) {\r\n\t\t\tconst possibleTargets = defendingBoard\r\n\t\t\t\t.filter((e) => !e.definitelyDead && e.health > 0)\r\n\t\t\t\t.filter((e) => !result.includes(e));\r\n\t\t\t// console.debug('possibleTargets', stringifySimple(possibleTargets, allCards));\r\n\t\t\tif (!possibleTargets.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tconst targetGroups = groupByFunction((e: BoardEntity) => Math.abs(defendingBoard.indexOf(e) - targetIndex))(\r\n\t\t\t\tpossibleTargets,\r\n\t\t\t);\r\n\t\t\tconst distances = Object.keys(targetGroups)\r\n\t\t\t\t.map((k) => +k)\r\n\t\t\t\t.sort();\r\n\t\t\tconst nearestDistance = distances[0];\r\n\t\t\tif (nearestDistance != null) {\r\n\t\t\t\t// console.debug(\r\n\t\t\t\t// \t'targetGroups[nearestDistance]',\r\n\t\t\t\t// \tnearestDistance,\r\n\t\t\t\t// \tstringifySimple(targetGroups[nearestDistance], allCards),\r\n\t\t\t\t// );\r\n\t\t\t\tconst target = pickRandom(targetGroups[nearestDistance]);\r\n\t\t\t\tresult.push(target);\r\n\t\t\t}\r\n\t\t\t// console.debug('\\n');\r\n\t\t}\r\n\t}\r\n\treturn result.filter((e) => !!e);\r\n};\r\n\r\nexport const getNeighbours = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n\talwaysIncludeBoth = false,\r\n): readonly BoardEntity[] => {\r\n\tconst neighbours = [];\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\tneighbours.push(leftNeighbour);\r\n\t\t}\r\n\r\n\t\t// If the deadEntityIndexFromRight === 0 (right-most minion), no neighbour will be found\r\n\t\tconst rightNeighbourIndex = board.length - 1 - (deadEntityIndexFromRight - 1);\r\n\t\tconst rightNeighbour = board[rightNeighbourIndex];\r\n\t\tif (rightNeighbour) {\r\n\t\t\tneighbours.push(rightNeighbour);\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\tneighbours.push(board[index - 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t\t// neighbours.push(entity);\r\n\t\tif (index + 1 < board.length) {\r\n\t\t\tneighbours.push(board[index + 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t}\r\n\treturn neighbours;\r\n};\r\n\r\nexport const getLeftNeighbour = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n): BoardEntity => {\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\treturn leftNeighbour;\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\treturn board[index - 1];\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const dealDamageToRandomEnemy = (\r\n\tboardToBeDamaged: BoardEntity[],\r\n\tboardToBeDamagedHero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity,\r\n\tdamage: number,\r\n\tboardWithAttackOrigin: BoardEntity[],\r\n\tboardWithAttackOriginHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (boardToBeDamaged.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\tconst validTargets = boardToBeDamaged.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst defendingEntity: BoardEntity = pickRandom(validTargets);\r\n\tif (defendingEntity) {\r\n\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\tdamageSource,\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t);\r\n\t\tdealDamageToMinion(\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tdamageSource,\r\n\t\t\tdamage,\r\n\t\t\tboardWithAttackOrigin,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n};\r\n\r\nexport const dealDamageToMinion = (\r\n\ttarget: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!target) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst isDeadBeforeDamage = target.definitelyDead || target.health <= 0;\r\n\tconst spawns = [];\r\n\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t// without it\r\n\tconst fakeAttacker = {\r\n\t\t...(damageSource || {}),\r\n\t\tentityId: -1,\r\n\t\tattack: damage,\r\n\t\t// attacking: true,\r\n\t} as BoardEntity;\r\n\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\r\n\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t// cause wrong results to happen\r\n\t// TODO: why isn't it done in bumpEntities?\r\n\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t// the divine shield once both bumps are done\r\n\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t}\r\n\r\n\tif (actualDamageDone > 0) {\r\n\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\ttarget,\r\n\t\t\tboard,\r\n\t\t\thero,\r\n\t\t\totherBoard,\r\n\t\t\totherHero,\r\n\t\t\tdamageSource,\r\n\t\t\tactualDamageDone,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tif (isBoardEntity(damageSource)) {\r\n\t\t\tdamageSource.venomous = false;\r\n\t\t}\r\n\t}\r\n\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\r\n\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\tonMinionKill(damageSource as BoardEntity, false, target, otherBoard, otherHero, board, hero, [], gameState);\r\n\t\t}\r\n\t}\r\n\tconst defendingEntityIndex = board.findIndex((entity) => entity.entityId === target.entityId);\r\n\tboard[defendingEntityIndex] = target;\r\n\treturn actualDamageDone;\r\n};\r\n\r\n// Because the \"onEntityDamaged\" effect is only called once all the minions are damaged\r\nexport const dealDamageToMinions = (\r\n\ttargets: BoardEntity[],\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!targets?.length) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst actualDamagesDone = [];\r\n\tconst areDeadBeforeDamage = targets.map((target) => target.definitelyDead || target.health <= 0);\r\n\r\n\tfor (const target of targets) {\r\n\t\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t\t// without it\r\n\t\tconst fakeAttacker = {\r\n\t\t\t...(damageSource || {}),\r\n\t\t\tentityId: -1,\r\n\t\t\tattack: damage,\r\n\t\t\t// attacking: true,\r\n\t\t} as BoardEntity;\r\n\t\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\t\tactualDamagesDone.push(actualDamageDone);\r\n\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// TODO: why isn't it done in bumpEntities?\r\n\t\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t\t// the divine shield once both bumps are done\r\n\t\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\t\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t\t}\r\n\t}\r\n\r\n\tconst spawns = [];\r\n\tfor (let i = 0; i < targets.length; i++) {\r\n\t\tconst target = targets[i];\r\n\t\tconst actualDamageDone = actualDamagesDone[i];\r\n\t\tconst isDeadBeforeDamage = areDeadBeforeDamage[i];\r\n\t\tif (actualDamageDone > 0) {\r\n\t\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\t\ttarget,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tdamageSource,\r\n\t\t\t\tactualDamageDone,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\r\n\t\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\t\tonMinionKill(\r\n\t\t\t\t\tdamageSource as BoardEntity,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tboard,\r\n\t\t\t\t\thero,\r\n\t\t\t\t\t[],\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\tconst defendingEntityIndex = board.map((entity) => entity.entityId).indexOf(target.entityId);\r\n\t\tboard[defendingEntityIndex] = target;\r\n\t}\r\n\treturn actualDamagesDone.reduce((a, b) => a + b, 0);\r\n};\r\n\r\nexport const getDefendingEntity = (\r\n\tdefendingBoard: BoardEntity[],\r\n\tattackingEntity: BoardEntity,\r\n\tignoreTaunts = false,\r\n): BoardEntity => {\r\n\tif (debugState.active) {\r\n\t\tfor (const forcedFaceOff of debugState.forcedFaceOff) {\r\n\t\t\tif (debugState.isCorrectEntity(forcedFaceOff.attacker, attackingEntity)) {\r\n\t\t\t\t// if (attackingEntity.entityId === forcedFaceOff.attacker.entityId) {\r\n\t\t\t\tconst def = defendingBoard.find((e) => debugState.isCorrectEntity(forcedFaceOff.defender, e));\r\n\t\t\t\tif (!!def) {\r\n\t\t\t\t\t// Remove the face-off\r\n\t\t\t\t\tdebugState.forcedFaceOff = debugState.forcedFaceOff.filter((f) => f != forcedFaceOff);\r\n\t\t\t\t\treturn def;\r\n\t\t\t\t}\r\n\t\t\t\t// }\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tlet possibleDefenders: readonly BoardEntity[];\r\n\tif (\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_BGS_022 ||\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_TB_BaconUps_091 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845_G\r\n\t) {\r\n\t\tconst minAttack = Math.min(...defendingBoard.map((entity) => entity.attack));\r\n\t\tpossibleDefenders = defendingBoard.filter((entity) => entity.attack === minAttack);\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921 ||\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921_G\r\n\t) {\r\n\t\tpossibleDefenders = defendingBoard\r\n\t\t\t.filter(\r\n\t\t\t\t(entity) =>\r\n\t\t\t\t\tentity.health <= attackingEntity.attack || attackingEntity.venomous || attackingEntity.poisonous,\r\n\t\t\t)\r\n\t\t\t.filter((e) => !e.divineShield);\r\n\t\tif (!possibleDefenders.length) {\r\n\t\t\tpossibleDefenders = defendingBoard;\r\n\t\t}\r\n\t} else {\r\n\t\tpossibleDefenders = defendingBoard.filter((e) => !e.stealth);\r\n\t\tif (!ignoreTaunts) {\r\n\t\t\tconst taunts = possibleDefenders.filter((entity) => entity.taunt);\r\n\t\t\tpossibleDefenders = taunts.length > 0 ? taunts : possibleDefenders;\r\n\t\t}\r\n\t}\r\n\r\n\tconst chosenDefender = pickRandom(possibleDefenders);\r\n\t// if (chosenDefender?.taunt) {\r\n\t// \tconst elistras = defendingBoard.filter(\r\n\t// \t\t(entity) =>\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_BGS_205 ||\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_TB_BaconUps_306,\r\n\t// \t);\r\n\t// \tif (elistras.length > 0) {\r\n\t// \t\tchosenDefender = elistras[Math.floor(Math.random() * elistras.length)];\r\n\t// \t}\r\n\t// }\r\n\treturn chosenDefender;\r\n};\r\n\r\nexport const bumpEntities = (\r\n\tentity: BoardEntity,\r\n\tbumpInto: BoardEntity,\r\n\tentityBoard: BoardEntity[],\r\n\tentityBoardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tapplyVenomous = true,\r\n\tforceVenomous = false,\r\n): number => {\r\n\t// No attack has no impact\r\n\tconst debug = bumpInto.cardId === 'BG26_888';\r\n\tif (bumpInto.attack === 0) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// Matador effect has priority\r\n\tif (\r\n\t\tentity.abiityChargesLeft > 0 &&\r\n\t\t(entity.cardId === CardIds.MadMatador_BG28_404 || entity.cardId === CardIds.MadMatador_BG28_404_G)\r\n\t) {\r\n\t\tentity.abiityChargesLeft--;\r\n\t\tconst newTarget = pickRandom(otherBoard);\r\n\t\tif (newTarget) {\r\n\t\t\tgameState.spectator.registerPowerTarget(entity, newTarget, otherBoard, entityBoardHero, otherHero);\r\n\t\t\t// TODO: here the MadMatador is the source of the damage, not the initial attacker\r\n\t\t\t// Not sure exactly what the impact would be, as there is no counter\r\n\t\t\tconst newSource = {\r\n\t\t\t\t...entity,\r\n\t\t\t\tattack: bumpInto.attack,\r\n\t\t\t\t// attacking: true,\r\n\t\t\t} as BoardEntity;\r\n\t\t\tconst defenderHadDivineShield = newTarget.divineShield;\r\n\t\t\tconst damageDone = bumpEntities(\r\n\t\t\t\tnewTarget,\r\n\t\t\t\tnewSource,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tentityBoard,\r\n\t\t\t\tentityBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\tfalse,\r\n\t\t\t);\r\n\t\t\tif (newSource.attack > 0 && defenderHadDivineShield) {\r\n\t\t\t\tupdateDivineShield(newTarget, otherBoard, otherHero, entityBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (damageDone > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tnewTarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tentityBoard,\r\n\t\t\t\t\tentityBoardHero,\r\n\t\t\t\t\tnewSource,\r\n\t\t\t\t\tdamageDone,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\treturn damageDone;\r\n\t\t}\r\n\t}\r\n\r\n\tif (entity.divineShield) {\r\n\t\tgameState.spectator.registerDamageDealt(bumpInto, entity, 0, entityBoard);\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst damageDealt = (entity.damageMultiplier || 1) * bumpInto.attack;\r\n\tentity.health = entity.health - damageDealt;\r\n\t// FIXME: This will likely be incorrect in terms of timings, e.g. if the entity ends up\r\n\t// surviving following a buff like Spawn.\r\n\tgameState.spectator.registerDamageDealt(bumpInto, entity, damageDealt, entityBoard);\r\n\r\n\t// if (entity.cardId === CardIds.Bubblette_BG_TID_713 && bumpInto.attack === 1) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// } else if (entity.cardId === CardIds.Bubblette_BG_TID_713_G && bumpInto.attack === 2) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// }\r\n\t// Do it last, so that other effects are still processed\r\n\tif (bumpInto.poisonous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t}\r\n\tif ((bumpInto.venomous || forceVenomous) && applyVenomous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t\tupdateVenomous(bumpInto, false, otherBoard, otherHero, entityBoardHero, gameState);\r\n\t}\r\n\t// Ideally we should do the Reckoning stuff here. However, at this point we only have half the damage\r\n\t// information, so it is possible that the entity deals more than 3 (which should trigger Reckoning)\r\n\t// but dies during the exchange (and Reckoning doesn't trigger then)\r\n\r\n\tentity.lastAffectedByEntity = bumpInto;\r\n\t// if (entity.frenzyChargesLeft > 0 && entity.health > 0 && !entity.definitelyDead) {\r\n\t// \tapplyFrenzy(entity, entityBoard, entityBoardHero, gameState);\r\n\t// \tentity.frenzyChargesLeft--;\r\n\t// }\r\n\r\n\t// We spawn them here, because it says \"whenever\", and so happens right away\r\n\t// FIXME: there could be a bug here, if a Cleave attacks several IGB at the same time. The current\r\n\t// implementation could spawn minions above the max board size. Fringe case though, so leaving it\r\n\t// like this for now\r\n\t// const entitySpawns = getWheneverEntitySpawns(\r\n\t// \tentity,\r\n\t// \tentityBoard,\r\n\t// \tentityBoardHero,\r\n\t// \totherBoard,\r\n\t// \totherHero,\r\n\t// \tgameState.allCards,\r\n\t// \tgameState.cardsData,\r\n\t// \tgameState.sharedState,\r\n\t// \tgameState.spectator,\r\n\t// );\r\n\t// if (!!entitySpawns?.length) {\r\n\t// \t// Spawn to the right\r\n\t// \tconst index = entityBoard.map((e) => e.entityId).indexOf(entity.entityId) + 1;\r\n\t// \taddMinionsToBoard(entityBoard, entityBoardHero, otherHero, index, entitySpawns, gameState);\r\n\t// \tgameState.spectator.registerMinionsSpawn(entity, entityBoard, entitySpawns);\r\n\t// }\r\n\treturn bumpInto.attack;\r\n};\r\n\r\n// const getWheneverEntitySpawns = (\r\n// \tentity: BoardEntity,\r\n// \tentityBoard: BoardEntity[],\r\n// \tentityBoardHero: BgsPlayerEntity,\r\n// \totherBoard: BoardEntity[],\r\n// \totherHero: BgsPlayerEntity,\r\n// \tallCards: AllCardsService,\r\n// \tcardsData: CardsData,\r\n// \tsharedState: SharedState,\r\n// \tspectator: Spectator,\r\n// ): readonly BoardEntity[] => {\r\n// \tif (entityBoard.length === 7) {\r\n// \t\treturn null;\r\n// \t}\r\n\r\n// \tif (entity.cardId === CardIds.ImpGangBoss_BRM_006) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_BRM_006t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpGangBoss_TB_BaconUps_030) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_TB_BaconUps_030t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpMama_BGS_044) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.ImpMama_TB_BaconUps_116) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t2,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_BOT_218) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_BOT_218t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_TB_BaconUps_041) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_TB_BaconUps_041t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t}\r\n// \treturn null;\r\n// };\r\n\r\nexport const processMinionDeath = (\r\n\tboard1: BoardEntity[],\r\n\tboard1Hero: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tboard2Hero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\t// When we're in an \"attack immediately\" phase, we wait until we're out of the phase to summon minions\r\n\tskipSummonWhenSpace = false,\r\n): void => {\r\n\t// const debug = board1.some((e) => e.health <= 0) || board2.some((e) => e.health <= 0);\r\n\t// debug && console.debug('\\nprocessing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\tconst [deadMinionIndexesFromLeft1, deadMinionIndexesFromRights1, deadEntities1] = makeMinionsDie(\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\tconst [deadMinionIndexesFromLeft2, deadMinionIndexesFromRights2, deadEntities2] = makeMinionsDie(\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tgameState,\r\n\t);\r\n\t// debug && console.debug('after processing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\t// debug && console.debug(deadMinionIndexesFromRights1);\r\n\t// debug && console.debug(deadMinionIndexesFromRights2);\r\n\t// console.debug('dead entities', stringifySimple(deadEntities1, allCards), stringifySimple(deadEntities2, allCards));\r\n\t// No death to process, we can return\r\n\tif (deadEntities1.length === 0 && deadEntities2.length === 0) {\r\n\t\treturn;\r\n\t\t// return [board1, board2];\r\n\t}\r\n\r\n\t// Remember them right away, so that subsequent deaths do not break the order\r\n\t// TODO: move this to the deathrattle-orchestration?\r\n\t// If the fish dies (from Scallywag for instance), it doesn't remember the deathrattle\r\n\t// console.debug(\r\n\t// \t'\\n\\ndeadEntities',\r\n\t// \tstringifySimple(deadEntities1, gameState.allCards),\r\n\t// \tstringifySimple(deadEntities2, gameState.allCards),\r\n\t// );\r\n\r\n\tgameState.spectator.registerDeadEntities(\r\n\t\tdeadMinionIndexesFromRights1,\r\n\t\tdeadEntities1,\r\n\t\tboard1,\r\n\t\tdeadMinionIndexesFromRights2,\r\n\t\tdeadEntities2,\r\n\t\tboard2,\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities1.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft1[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities2.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft2[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\r\n\tfor (const deadEntity of deadEntities1) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board1Hero,\r\n\t\t\t\tboard: board1,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const deadEntity of deadEntities2) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board2Hero,\r\n\t\t\t\tboard: board2,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tboard1Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard1Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities1.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\tboard2Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard2Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities2.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\r\n\torchestrateMinionDeathEffects({\r\n\t\tgameState: gameState,\r\n\t\tplayerDeadEntities: board1Hero.friendly ? deadEntities1 : deadEntities2,\r\n\t\tplayerDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights1\r\n\t\t\t: deadMinionIndexesFromRights2,\r\n\t\topponentDeadEntities: board1Hero.friendly ? deadEntities2 : deadEntities1,\r\n\t\topponentDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights2\r\n\t\t\t: deadMinionIndexesFromRights1,\r\n\t});\r\n\r\n\t// Make sure we only return when there are no more deaths to process\r\n\t// Make sure to do this right before the end of the process\r\n\t// FIXME: this will propagate the killer between rounds, which is incorrect. For instance,\r\n\t// if a dragon kills a Ghoul, then the Ghoul's deathrattle kills a Kaboom, the killer should\r\n\t// now be the ghoul. Then if the Kaboom kills someone, the killer should again change. You could\r\n\t// also have multiple killers, which is not taken into account here.\r\n\t// The current assumption is that it's a suffienctly fringe case to not matter too much\r\n\tprocessMinionDeath(board1, board1Hero, board2, board2Hero, gameState);\r\n\r\n\t// Not sure about the timing here, but I have bothered Mitchell quite a lot already recently :)\r\n\tif (!skipSummonWhenSpace) {\r\n\t\thandleSummonsWhenSpace(board1, board1Hero, board2, board2Hero, gameState);\r\n\t}\r\n\r\n\t// Apply \"after minion death\" effects\r\n\thandleAfterMinionsDeaths(\r\n\t\tboard1,\r\n\t\tdeadEntities1,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights1 : deadMinionIndexesFromRights2,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tdeadEntities2,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights2 : deadMinionIndexesFromRights1,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\r\n\t// Only when all deathrattles have resolved\r\n\t// 2025-12-20: https://replays.firestoneapp.com/?reviewId=7d8f9af4-b484-4256-976b-ff9df8847b50&turn=5&action=0\r\n\t// Confirmed by dev that the fish doesn't get the deathrattle in this case\r\n\tboard1\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities1, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\tboard2\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities2, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\r\n\tresolvePendingEffects(board1, board1Hero, board2, board2Hero, gameState);\r\n};\r\n\r\nconst handleAfterMinionsDeaths = (\r\n\tboard1: BoardEntity[],\r\n\tdeadEntities1: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight1: number[],\r\n\theroEntity1: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tdeadEntities2: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight2: number[],\r\n\theroEntity2: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst random = Math.random() > 0.5;\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\trandom ? board1 : board2,\r\n\t\trandom ? deadEntities1 : deadEntities2,\r\n\t\trandom ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\trandom ? heroEntity1 : heroEntity2,\r\n\t\trandom ? board2 : board1,\r\n\t\trandom ? deadEntities2 : deadEntities1,\r\n\t\trandom ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\trandom ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\t!random ? board1 : board2,\r\n\t\t!random ? deadEntities1 : deadEntities2,\r\n\t\t!random ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\t!random ? heroEntity1 : heroEntity2,\r\n\t\t!random ? board2 : board1,\r\n\t\t!random ? deadEntities2 : deadEntities1,\r\n\t\t!random ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\t!random ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nconst handleAfterMinionsDeathsForBoard = (\r\n\tfriendlyBoard: BoardEntity[],\r\n\tfriendlyDeadEntities: BoardEntity[],\r\n\tfriendlyDeadEntitiesIndexesFromRight: number[],\r\n\tfriendlyHeroEntity: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherDeadEntities: BoardEntity[],\r\n\totherDeadEntitiesIndexesFromRight: number[],\r\n\totherHeroEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities = [];\r\n\r\n\tfor (const trinket of friendlyHeroEntity.trinkets ?? []) {\r\n\t\tconst onAfterDeathImpl = cardMappings[trinket.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(trinket, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const entity of friendlyBoard) {\r\n\t\tconst onAfterDeathImpl = cardMappings[entity.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(entity, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tconst secretTriggered = null;\r\n\t// if (\r\n\t// \t(secretTriggered = friendlyHeroEntity.secrets?.find(\r\n\t// \t\t(secret) => !secret.triggered && secret?.cardId === CardIds.MagicBlackSoulstone,\r\n\t// \t)) != null\r\n\t// ) {\r\n\t// \tif (friendlyBoard.length === 0) {\r\n\t// \t\tsecretTriggered.triggered = true;\r\n\t// \t\tfor (let i = 0; i < 2; i++) {\r\n\t// \t\t\tconst toSummon = pickRandom(gameState.cardsData.demonSpawns);\r\n\t// \t\t\tcandidateEntities.push(\r\n\t// \t\t\t\t...spawnEntities(\r\n\t// \t\t\t\t\ttoSummon,\r\n\t// \t\t\t\t\t1,\r\n\t// \t\t\t\t\tfriendlyBoard,\r\n\t// \t\t\t\t\tfriendlyHeroEntity,\r\n\t// \t\t\t\t\totherBoard,\r\n\t// \t\t\t\t\totherHeroEntity,\r\n\t// \t\t\t\t\tgameState,\r\n\t// \t\t\t\t\tfriendlyHeroEntity.friendly,\r\n\t// \t\t\t\t\tfalse,\r\n\t// \t\t\t\t),\r\n\t// \t\t\t);\r\n\t// \t\t}\r\n\t// \t}\r\n\t// }\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tfriendlyBoard,\r\n\t\tfriendlyHeroEntity,\r\n\t\tsecretTriggered,\r\n\t\t0,\r\n\t\totherBoard,\r\n\t\totherHeroEntity,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport interface OnDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnAfterDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly deadEntities: BoardEntity[];\r\n\treadonly deadEntitiesIndexesFromRight: number[];\r\n\treadonly gameState: FullGameState;\r\n}\r\n\r\n/** A friendly board minion just died (during death processing). Implementations filter (e.g. Taunt) as needed. */\r\nexport interface OnAfterFriendlyMinionDeathInput {\r\n\treadonly deadEntity: BoardEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly boardBeforeProcs: BoardEntity[];\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnMinionKilledInput {\r\n\treadonly killer: BoardEntity;\r\n\treadonly killerIsAttacking: boolean;\r\n\treadonly minionKilled: BoardEntity;\r\n\treadonly attackingHero: BgsPlayerEntity;\r\n\treadonly attackingBoard: BoardEntity[];\r\n\treadonly defendingHero: BgsPlayerEntity;\r\n\treadonly defendingBoard: BoardEntity[];\r\n\treadonly defenderNeighbours: readonly BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n\treadonly playerIsFriendly: boolean;\r\n}\r\n"]}
|
|
@@ -6,7 +6,7 @@ import { FullGameState } from './internal-game-state';
|
|
|
6
6
|
export declare const setMissingAuras: (board: BoardEntity[], boardHero: BgsPlayerEntity, anomalies: readonly string[], allCards: AllCardsService) => void;
|
|
7
7
|
export declare const setMissingTrinketAura: (board: BoardEntity[], boardHero: BgsPlayerEntity) => void;
|
|
8
8
|
export declare const setMissingHeroPowerAura: (board: BoardEntity[], boardHero: BgsPlayerEntity) => void;
|
|
9
|
-
export declare const setImplicitDataHero: (hero: BgsPlayerEntity, cardsData: CardsData, isPlayer: boolean, entityIdContainer: {
|
|
9
|
+
export declare const setImplicitDataHero: (hero: BgsPlayerEntity, board: BoardEntity[], cardsData: CardsData, isPlayer: boolean, entityIdContainer: {
|
|
10
10
|
entityId: number;
|
|
11
11
|
}) => void;
|
|
12
12
|
export declare const clearStealthIfNeeded: (board: BoardEntity[], hero: BgsPlayerEntity, otherBoard: BoardEntity[], otherHero: BgsPlayerEntity, gameState: FullGameState) => void;
|
package/dist/simulation/auras.js
CHANGED
|
@@ -79,8 +79,8 @@ const setMissingAura = (board, minionCardId, enchantmentCardId, attack, health,
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
|
-
const setImplicitDataHero = (hero, cardsData, isPlayer, entityIdContainer) => {
|
|
83
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35;
|
|
82
|
+
const setImplicitDataHero = (hero, board, cardsData, isPlayer, entityIdContainer) => {
|
|
83
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37;
|
|
84
84
|
for (const heroPower of hero.heroPowers) {
|
|
85
85
|
const avengeValue = cardsData.avengeValue(heroPower.cardId);
|
|
86
86
|
if (avengeValue > 0) {
|
|
@@ -131,59 +131,72 @@ const setImplicitDataHero = (hero, cardsData, isPlayer, entityIdContainer) => {
|
|
|
131
131
|
if (!hero.globalInfo) {
|
|
132
132
|
hero.globalInfo = {};
|
|
133
133
|
}
|
|
134
|
-
hero.globalInfo.
|
|
135
|
-
hero.globalInfo.
|
|
136
|
-
hero.globalInfo.
|
|
137
|
-
hero.globalInfo.
|
|
138
|
-
hero.globalInfo.
|
|
139
|
-
hero.globalInfo.
|
|
140
|
-
hero.globalInfo.
|
|
141
|
-
hero.globalInfo.
|
|
142
|
-
hero.globalInfo.
|
|
143
|
-
hero.globalInfo.
|
|
144
|
-
hero.globalInfo.
|
|
145
|
-
hero.globalInfo.
|
|
146
|
-
hero.globalInfo.
|
|
147
|
-
hero.globalInfo.
|
|
148
|
-
hero.globalInfo.
|
|
149
|
-
hero.globalInfo.
|
|
150
|
-
hero.globalInfo.
|
|
151
|
-
hero.globalInfo.
|
|
152
|
-
hero.globalInfo.
|
|
153
|
-
hero.globalInfo.
|
|
154
|
-
hero.globalInfo.
|
|
155
|
-
hero.globalInfo.
|
|
156
|
-
hero.globalInfo.
|
|
157
|
-
hero.globalInfo.
|
|
158
|
-
hero.globalInfo.
|
|
159
|
-
hero.globalInfo.
|
|
160
|
-
hero.globalInfo.
|
|
161
|
-
hero.globalInfo.
|
|
162
|
-
hero.globalInfo.
|
|
163
|
-
hero.globalInfo.
|
|
164
|
-
hero.globalInfo.
|
|
165
|
-
hero.globalInfo.
|
|
134
|
+
hero.globalInfo.PirateAttackBonus = (_h = hero.globalInfo.PirateAttackBonus) !== null && _h !== void 0 ? _h : 0;
|
|
135
|
+
hero.globalInfo.MechAttackBonus = (_j = hero.globalInfo.MechAttackBonus) !== null && _j !== void 0 ? _j : 0;
|
|
136
|
+
hero.globalInfo.EternalKnightsDeadThisGame = (_k = hero.globalInfo.EternalKnightsDeadThisGame) !== null && _k !== void 0 ? _k : 0;
|
|
137
|
+
hero.globalInfo.EternalKnightAttackBuff = (_l = hero.globalInfo.EternalKnightAttackBuff) !== null && _l !== void 0 ? _l : 0;
|
|
138
|
+
hero.globalInfo.EternalKnightHealthBuff = (_m = hero.globalInfo.EternalKnightHealthBuff) !== null && _m !== void 0 ? _m : 0;
|
|
139
|
+
hero.globalInfo.SanlaynScribesDeadThisGame = (_o = hero.globalInfo.SanlaynScribesDeadThisGame) !== null && _o !== void 0 ? _o : 0;
|
|
140
|
+
hero.globalInfo.BeastsSummonedThisGame = (_p = hero.globalInfo.BeastsSummonedThisGame) !== null && _p !== void 0 ? _p : 0;
|
|
141
|
+
hero.globalInfo.BeastsSummonedThisCombat = (_q = hero.globalInfo.BeastsSummonedThisCombat) !== null && _q !== void 0 ? _q : 0;
|
|
142
|
+
hero.globalInfo.MagnetizedThisGame = (_r = hero.globalInfo.MagnetizedThisGame) !== null && _r !== void 0 ? _r : 0;
|
|
143
|
+
hero.globalInfo.PiratesSummonedThisGame = (_s = hero.globalInfo.PiratesSummonedThisGame) !== null && _s !== void 0 ? _s : 0;
|
|
144
|
+
hero.globalInfo.AstralAutomatonsSummonedThisGame = (_t = hero.globalInfo.AstralAutomatonsSummonedThisGame) !== null && _t !== void 0 ? _t : 0;
|
|
145
|
+
hero.globalInfo.BattlecriesTriggeredThisGame = (_u = hero.globalInfo.BattlecriesTriggeredThisGame) !== null && _u !== void 0 ? _u : 0;
|
|
146
|
+
hero.globalInfo.DeathrattlesTriggeredThisGame = (_v = hero.globalInfo.DeathrattlesTriggeredThisGame) !== null && _v !== void 0 ? _v : 0;
|
|
147
|
+
hero.globalInfo.BeetleAttackBuff = (_w = hero.globalInfo.BeetleAttackBuff) !== null && _w !== void 0 ? _w : 0;
|
|
148
|
+
hero.globalInfo.BeetleHealthBuff = (_x = hero.globalInfo.BeetleHealthBuff) !== null && _x !== void 0 ? _x : 0;
|
|
149
|
+
hero.globalInfo.ElementalAttackBuff = (_y = hero.globalInfo.ElementalAttackBuff) !== null && _y !== void 0 ? _y : 0;
|
|
150
|
+
hero.globalInfo.ElementalHealthBuff = (_z = hero.globalInfo.ElementalHealthBuff) !== null && _z !== void 0 ? _z : 0;
|
|
151
|
+
hero.globalInfo.PirateAttackBuff = (_0 = hero.globalInfo.PirateAttackBuff) !== null && _0 !== void 0 ? _0 : 0;
|
|
152
|
+
hero.globalInfo.PirateHealthBuff = (_1 = hero.globalInfo.PirateHealthBuff) !== null && _1 !== void 0 ? _1 : 0;
|
|
153
|
+
hero.globalInfo.TavernSpellAttackBuff = (_2 = hero.globalInfo.TavernSpellAttackBuff) !== null && _2 !== void 0 ? _2 : 0;
|
|
154
|
+
hero.globalInfo.TavernSpellHealthBuff = (_3 = hero.globalInfo.TavernSpellHealthBuff) !== null && _3 !== void 0 ? _3 : 0;
|
|
155
|
+
hero.globalInfo.MutatedLasherAttackBuff = (_4 = hero.globalInfo.MutatedLasherAttackBuff) !== null && _4 !== void 0 ? _4 : 0;
|
|
156
|
+
hero.globalInfo.MutatedLasherHealthBuff = (_5 = hero.globalInfo.MutatedLasherHealthBuff) !== null && _5 !== void 0 ? _5 : 0;
|
|
157
|
+
hero.globalInfo.TavernSpellsCastThisGame = (_6 = hero.globalInfo.TavernSpellsCastThisGame) !== null && _6 !== void 0 ? _6 : 0;
|
|
158
|
+
hero.globalInfo.TavernSpellsCastThisTurn = (_7 = hero.globalInfo.TavernSpellsCastThisTurn) !== null && _7 !== void 0 ? _7 : 0;
|
|
159
|
+
hero.globalInfo.CardsPlayedThisTurn = (_8 = hero.globalInfo.CardsPlayedThisTurn) !== null && _8 !== void 0 ? _8 : 0;
|
|
160
|
+
hero.globalInfo.MrrgltonsPlayedThisGame = (_9 = hero.globalInfo.MrrgltonsPlayedThisGame) !== null && _9 !== void 0 ? _9 : 0;
|
|
161
|
+
hero.globalInfo.AdditionalAttack = (_10 = hero.globalInfo.AdditionalAttack) !== null && _10 !== void 0 ? _10 : 0;
|
|
162
|
+
hero.globalInfo.SpellsCastThisGame = (_11 = hero.globalInfo.SpellsCastThisGame) !== null && _11 !== void 0 ? _11 : 0;
|
|
163
|
+
hero.globalInfo.UndeadAttackBonus = (_12 = hero.globalInfo.UndeadAttackBonus) !== null && _12 !== void 0 ? _12 : 0;
|
|
164
|
+
hero.globalInfo.UndeadHealthBonus = (_13 = hero.globalInfo.UndeadHealthBonus) !== null && _13 !== void 0 ? _13 : 0;
|
|
165
|
+
hero.globalInfo.HauntedCarapaceAttackBonus = (_14 = hero.globalInfo.HauntedCarapaceAttackBonus) !== null && _14 !== void 0 ? _14 : 0;
|
|
166
|
+
hero.globalInfo.HauntedCarapaceHealthBonus = (_15 = hero.globalInfo.HauntedCarapaceHealthBonus) !== null && _15 !== void 0 ? _15 : 0;
|
|
167
|
+
hero.globalInfo.FrostlingBonus = (_16 = hero.globalInfo.FrostlingBonus) !== null && _16 !== void 0 ? _16 : 0;
|
|
166
168
|
hero.globalInfo.BloodGemAttackBonus =
|
|
167
|
-
((
|
|
168
|
-
((
|
|
169
|
+
((_17 = hero.globalInfo.BloodGemAttackBonus) !== null && _17 !== void 0 ? _17 : 0) +
|
|
170
|
+
((_19 = (_18 = hero.questRewardEntities) === null || _18 === void 0 ? void 0 : _18.filter((e) => e.cardId === "BG27_Reward_815").length) !== null && _19 !== void 0 ? _19 : 0);
|
|
169
171
|
hero.globalInfo.BloodGemHealthBonus =
|
|
170
|
-
((
|
|
171
|
-
((
|
|
172
|
-
hero.globalInfo.GoldrinnBuffAtk = (
|
|
173
|
-
hero.globalInfo.GoldrinnBuffHealth = (
|
|
174
|
-
hero.globalInfo.WhelpAttackBuff = (
|
|
175
|
-
hero.globalInfo.WhelpHealthBuff = (
|
|
176
|
-
hero.globalInfo.GoldSpentThisGame = (
|
|
177
|
-
hero.globalInfo.VolumizerAttackBuff = (
|
|
178
|
-
hero.globalInfo.VolumizerHealthBuff = (
|
|
179
|
-
hero.globalInfo.DeepBluesPlayed = (
|
|
180
|
-
hero.globalInfo.
|
|
181
|
-
hero.globalInfo.
|
|
182
|
-
hero.globalInfo.
|
|
183
|
-
hero.globalInfo.
|
|
184
|
-
hero.globalInfo.
|
|
185
|
-
hero.globalInfo.
|
|
186
|
-
hero.globalInfo.
|
|
172
|
+
((_20 = hero.globalInfo.BloodGemHealthBonus) !== null && _20 !== void 0 ? _20 : 0) +
|
|
173
|
+
((_22 = (_21 = hero.questRewardEntities) === null || _21 === void 0 ? void 0 : _21.filter((e) => e.cardId === "BG27_Reward_815").length) !== null && _22 !== void 0 ? _22 : 0);
|
|
174
|
+
hero.globalInfo.GoldrinnBuffAtk = (_23 = hero.globalInfo.GoldrinnBuffAtk) !== null && _23 !== void 0 ? _23 : 0;
|
|
175
|
+
hero.globalInfo.GoldrinnBuffHealth = (_24 = hero.globalInfo.GoldrinnBuffHealth) !== null && _24 !== void 0 ? _24 : 0;
|
|
176
|
+
hero.globalInfo.WhelpAttackBuff = (_25 = hero.globalInfo.WhelpAttackBuff) !== null && _25 !== void 0 ? _25 : 0;
|
|
177
|
+
hero.globalInfo.WhelpHealthBuff = (_26 = hero.globalInfo.WhelpHealthBuff) !== null && _26 !== void 0 ? _26 : 0;
|
|
178
|
+
hero.globalInfo.GoldSpentThisGame = (_27 = hero.globalInfo.GoldSpentThisGame) !== null && _27 !== void 0 ? _27 : 0;
|
|
179
|
+
hero.globalInfo.VolumizerAttackBuff = (_28 = hero.globalInfo.VolumizerAttackBuff) !== null && _28 !== void 0 ? _28 : 0;
|
|
180
|
+
hero.globalInfo.VolumizerHealthBuff = (_29 = hero.globalInfo.VolumizerHealthBuff) !== null && _29 !== void 0 ? _29 : 0;
|
|
181
|
+
hero.globalInfo.DeepBluesPlayed = (_30 = hero.globalInfo.DeepBluesPlayed) !== null && _30 !== void 0 ? _30 : 0;
|
|
182
|
+
hero.globalInfo.GoldenMinionsPlayedThisGame = (_31 = hero.globalInfo.GoldenMinionsPlayedThisGame) !== null && _31 !== void 0 ? _31 : 0;
|
|
183
|
+
hero.globalInfo.DeathrattlesTriggeredThisGame = (_32 = hero.globalInfo.DeathrattlesTriggeredThisGame) !== null && _32 !== void 0 ? _32 : 0;
|
|
184
|
+
hero.globalInfo.BackToBackCastThisGame = (_33 = hero.globalInfo.BackToBackCastThisGame) !== null && _33 !== void 0 ? _33 : 0;
|
|
185
|
+
hero.globalInfo.TavernSpellsCastThisTurn = (_34 = hero.globalInfo.TavernSpellsCastThisTurn) !== null && _34 !== void 0 ? _34 : 0;
|
|
186
|
+
hero.globalInfo.CardsPlayedThisTurn = (_35 = hero.globalInfo.CardsPlayedThisTurn) !== null && _35 !== void 0 ? _35 : 0;
|
|
187
|
+
hero.globalInfo.MrrgltonsPlayedThisGame = (_36 = hero.globalInfo.MrrgltonsPlayedThisGame) !== null && _36 !== void 0 ? _36 : 0;
|
|
188
|
+
hero.globalInfo.TastyLobstersBuff = (_37 = hero.globalInfo.TastyLobstersBuff) !== null && _37 !== void 0 ? _37 : 0;
|
|
189
|
+
if (hero.globalInfo.TastyLobstersBuff === 0) {
|
|
190
|
+
hero.globalInfo.TastyLobstersBuff = board
|
|
191
|
+
.filter((e) => e.cardId === "BG36_202" || e.cardId === "BG36_202_G")
|
|
192
|
+
.map((e) => {
|
|
193
|
+
var _a;
|
|
194
|
+
const rawScript = (_a = e.scriptDataNum1) !== null && _a !== void 0 ? _a : 0;
|
|
195
|
+
const baseValue = e.cardId === "BG36_202" ? rawScript : rawScript / 2;
|
|
196
|
+
return baseValue;
|
|
197
|
+
})
|
|
198
|
+
.reduce((max, value) => Math.max(max, value), 0);
|
|
199
|
+
}
|
|
187
200
|
};
|
|
188
201
|
exports.setImplicitDataHero = setImplicitDataHero;
|
|
189
202
|
const clearStealthIfNeeded = (board, hero, otherBoard, otherHero, gameState) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auras.js","sourceRoot":"","sources":["../../src/simulation/auras.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardsData } from '../cards/cards-data';\r\nimport { updateStealth } from '../keywords/stealth';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { addImpliedMechanics, hasCorrectTribe } from '../utils';\r\nimport { FullGameState } from './internal-game-state';\r\n\r\nexport const setMissingAuras = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): void => {\r\n\tsetMissingMinionsAura(board, boardHero, anomalies, allCards);\r\n\tsetMissingHeroPowerAura(board, boardHero);\r\n\tsetMissingTrinketAura(board, boardHero);\r\n};\r\n\r\nexport const setMissingTrinketAura = (board: BoardEntity[], boardHero: BgsPlayerEntity): void => {\r\n\tfor (const trinket of boardHero.trinkets ?? []) {\r\n\t\t// switch (trinket.cardId) {\r\n\t\t// \tcase CardIds.WindrunnerNecklace_BG30_MagicItem_997:\r\n\t\t// \tcase CardIds.WindrunnerNecklace_WindrunnerNecklaceToken_BG30_MagicItem_997t:\r\n\t\t// \t\tconst enchantment =\r\n\t\t// \t\t\ttrinket.cardId === CardIds.WindrunnerNecklace_BG30_MagicItem_997\r\n\t\t// \t\t\t\t? CardIds.WindrunnerNecklace_RunningLikeTheWindEnchantment_BG30_MagicItem_997e\r\n\t\t// \t\t\t\t: CardIds.WindrunnerNecklace_RunningLikeTheWindEnchantment_BG30_MagicItem_997e2;\r\n\t\t// \t\tconst buff = trinket.cardId === CardIds.WindrunnerNecklace_BG30_MagicItem_997 ? 8 : 20;\r\n\t\t// \t\tconst target = board[0];\r\n\t\t// \t\tif (!!target && !target.enchantments?.find((e) => e.cardId === enchantment)) {\r\n\t\t// \t\t\ttarget.attack += buff;\r\n\t\t// \t\t\ttarget.enchantments.push({\r\n\t\t// \t\t\t\tcardId: enchantment,\r\n\t\t// \t\t\t\toriginEntityId: trinket.entityId,\r\n\t\t// \t\t\t\ttiming: 0,\r\n\t\t// \t\t\t});\r\n\t\t// \t\t}\r\n\t\t// \t\tbreak;\r\n\t\t// }\r\n\t}\r\n};\r\n\r\nexport const setMissingHeroPowerAura = (board: BoardEntity[], boardHero: BgsPlayerEntity): void => {\r\n\tfor (const heroPower of boardHero.heroPowers) {\r\n\t\tif (heroPower.cardId === CardIds.TheSmokingGun) {\r\n\t\t\tboard\r\n\t\t\t\t.filter(\r\n\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t!e.enchantments.find(\r\n\t\t\t\t\t\t\t(ench) => ench.cardId === CardIds.TheSmokingGun_ArmedAndStillSmokingEnchantment,\r\n\t\t\t\t\t\t),\r\n\t\t\t\t)\r\n\t\t\t\t.forEach((e) => {\r\n\t\t\t\t\te.attack += 4;\r\n\t\t\t\t});\r\n\t\t}\r\n\t\tif (heroPower.cardId === CardIds.VolatileVenom) {\r\n\t\t\tboard\r\n\t\t\t\t.filter(\r\n\t\t\t\t\t(e) => !e.enchantments.find((ench) => ench.cardId === CardIds.VolatileVenom_VolatileEnchantment),\r\n\t\t\t\t)\r\n\t\t\t\t.forEach((e) => {\r\n\t\t\t\t\te.attack += 7;\r\n\t\t\t\t\te.health += 7;\r\n\t\t\t\t\te.enchantments.push({\r\n\t\t\t\t\t\tcardId: CardIds.VolatileVenom_VolatileEnchantment,\r\n\t\t\t\t\t\toriginEntityId: undefined,\r\n\t\t\t\t\t\ttiming: 0,\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\nconst setMissingMinionsAura = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): void => {\r\n\tconst pirates: BoardEntity[] = [];\r\n\tconst murlocs: BoardEntity[] = [];\r\n\tconst undead: BoardEntity[] = [];\r\n\tconst divineShielded: BoardEntity[] = [];\r\n\tfor (const e of board) {\r\n\t\tif (e.divineShield) {\r\n\t\t\tdivineShielded.push(e);\r\n\t\t}\r\n\t\tif (hasCorrectTribe(e, boardHero, Race.PIRATE, anomalies, allCards)) {\r\n\t\t\tpirates.push(e);\r\n\t\t}\r\n\t\tif (hasCorrectTribe(e, boardHero, Race.MURLOC, anomalies, allCards)) {\r\n\t\t\tmurlocs.push(e);\r\n\t\t}\r\n\t\tif (hasCorrectTribe(e, boardHero, Race.UNDEAD, anomalies, allCards)) {\r\n\t\t\tundead.push(e);\r\n\t\t}\r\n\t}\r\n\tsetMissingAura(\r\n\t\tpirates,\r\n\t\tCardIds.SouthseaCaptainLegacy_BG_NEW1_027,\r\n\t\tCardIds.SouthseaCaptain_YarrrVanillaEnchantment,\r\n\t\t1,\r\n\t\t1,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tpirates,\r\n\t\tCardIds.SouthseaCaptainLegacy_TB_BaconUps_136,\r\n\t\tCardIds.SouthseaCaptain_YarrrEnchantment,\r\n\t\t2,\r\n\t\t2,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tmurlocs,\r\n\t\tCardIds.MurlocWarleaderLegacy_BG_EX1_507,\r\n\t\tCardIds.MurlocWarleader_MrgglaarglLegacyEnchantment,\r\n\t\t2,\r\n\t\t0,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tdivineShielded,\r\n\t\tCardIds.CyborgDrake_BG25_043,\r\n\t\tCardIds.CyborgDrake_CyborgEnhancementEnchantment_BG25_043e,\r\n\t\t6,\r\n\t\t0,\r\n\t\tfalse,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tundead,\r\n\t\tCardIds.SoreLoser_BG27_030,\r\n\t\tCardIds.SoreLoser_NoImWinningEnchantment_BG27_030e,\r\n\t\tboardHero.tavernTier,\r\n\t\t0,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tundead,\r\n\t\tCardIds.SoreLoser_BG27_030_G,\r\n\t\tCardIds.SoreLoser_NoImWinningEnchantment_BG27_030e,\r\n\t\t2 * boardHero.tavernTier,\r\n\t\t0,\r\n\t);\r\n};\r\n\r\nconst setMissingAura = (\r\n\tboard: BoardEntity[],\r\n\tminionCardId: string,\r\n\tenchantmentCardId: string,\r\n\tattack: number,\r\n\thealth: number,\r\n\tignoreSelf = true,\r\n\tallCards: AllCardsService = null,\r\n): void => {\r\n\tconst buffers = board.filter((e) => e.cardId === minionCardId);\r\n\tfor (const buffer of buffers) {\r\n\t\tboard\r\n\t\t\t.filter((e) => !e.enchantments.find((ench) => ench.cardId === enchantmentCardId))\r\n\t\t\t.filter((e) => (ignoreSelf ? e.entityId !== buffer.entityId : true))\r\n\t\t\t.forEach((e) => {\r\n\t\t\t\te.attack += attack;\r\n\t\t\t\te.health += health;\r\n\t\t\t});\r\n\t}\r\n};\r\n\r\nexport const setImplicitDataHero = (\r\n\thero: BgsPlayerEntity,\r\n\tcardsData: CardsData,\r\n\tisPlayer: boolean,\r\n\tentityIdContainer: { entityId: number },\r\n): void => {\r\n\tfor (const heroPower of hero.heroPowers) {\r\n\t\tconst avengeValue = cardsData.avengeValue(heroPower.cardId);\r\n\t\tif (avengeValue > 0) {\r\n\t\t\theroPower.avengeCurrent = avengeValue - (heroPower.scoreValue2 ?? 0);\r\n\t\t\theroPower.avengeDefault = avengeValue;\r\n\t\t}\r\n\t\tif ((heroPower.info as BoardEntity)?.health) {\r\n\t\t\taddImpliedMechanics(heroPower.info as BoardEntity, cardsData);\r\n\t\t}\r\n\t}\r\n\t// Backward compatibility\r\n\tif (!!hero.questRewards?.length && !Array.isArray(hero.questRewards)) {\r\n\t\thero.questRewards = [hero.questRewards as any];\r\n\t}\r\n\r\n\t// Because Denathrius can send a quest reward as its hero power (I think)\r\n\t// For now deactivating this, until I have a scenario where this matters. It feels like\r\n\t// this should be a display issue only, as quest rewards are also handled in the code\r\n\tconst heroPowerAsReward = null; // hero.cardId === CardIds.SireDenathrius_BG24_HERO_100 ? hero.heroPowers[0]?.cardId : null;\r\n\thero.questRewards = [...(hero.questRewards ?? []), heroPowerAsReward].filter((e) => !!e);\r\n\thero.questRewardEntities = hero.questRewardEntities\r\n\t\t? hero.questRewardEntities.map((reward: any) => ({\r\n\t\t\t\tcardId: reward.CardId,\r\n\t\t\t\tscriptDataNum1: reward.ScriptDataNum1 ?? 0,\r\n\t\t\t\tentityId: entityIdContainer.entityId--,\r\n\t\t\t\tavengeDefault: cardsData.avengeValue(reward.CardId),\r\n\t\t\t\tavengeCurrent: cardsData.avengeValue(reward.CardId),\r\n\t\t }))\r\n\t\t: hero.questRewards.map((reward) => ({\r\n\t\t\t\tcardId: reward,\r\n\t\t\t\tentityId: entityIdContainer.entityId--,\r\n\t\t\t\tavengeCurrent: cardsData.avengeValue(reward),\r\n\t\t\t\tavengeDefault: cardsData.avengeValue(reward),\r\n\t\t\t\tscriptDataNum1: cardsData.defaultScriptDataNum(reward),\r\n\t\t }));\r\n\thero.trinkets = (hero.trinkets ?? [])\r\n\t\t.map((trinket) => ({\r\n\t\t\t...trinket,\r\n\t\t\tavengeDefault: cardsData.avengeValue(trinket.cardId),\r\n\t\t\tavengeCurrent: cardsData.avengeValue(trinket.cardId),\r\n\t\t\t// Use scriptDataNum1 to keep the info from the input\r\n\t\t\t// We don't want to use the default value is the value from the game state is 0\r\n\t\t\t// In that case, we probably want to use the ChargesLeft mechanism\r\n\t\t\tscriptDataNum1: trinket.scriptDataNum1 ?? cardsData.defaultScriptDataNum(trinket.cardId),\r\n\t\t}))\r\n\t\t.sort((a, b) => a.entityId - b.entityId);\r\n\t// 0 is not a valid entityId\r\n\thero.entityId = hero.entityId || entityIdContainer.entityId--;\r\n\thero.hand = hero.hand ?? [];\r\n\thero.enchantments = hero.enchantments ?? [];\r\n\tif (!hero.globalInfo) {\r\n\t\thero.globalInfo = {};\r\n\t}\r\n\r\n\thero.globalInfo.EternalKnightsDeadThisGame = hero.globalInfo.EternalKnightsDeadThisGame ?? 0;\r\n\thero.globalInfo.EternalKnightAttackBuff = hero.globalInfo.EternalKnightAttackBuff ?? 0;\r\n\thero.globalInfo.EternalKnightHealthBuff = hero.globalInfo.EternalKnightHealthBuff ?? 0;\r\n\thero.globalInfo.SanlaynScribesDeadThisGame = hero.globalInfo.SanlaynScribesDeadThisGame ?? 0;\r\n\thero.globalInfo.BeastsSummonedThisGame = hero.globalInfo.BeastsSummonedThisGame ?? 0;\r\n\thero.globalInfo.BeastsSummonedThisCombat = hero.globalInfo.BeastsSummonedThisCombat ?? 0;\r\n\thero.globalInfo.MagnetizedThisGame = hero.globalInfo.MagnetizedThisGame ?? 0;\r\n\thero.globalInfo.PiratesSummonedThisGame = hero.globalInfo.PiratesSummonedThisGame ?? 0;\r\n\thero.globalInfo.AstralAutomatonsSummonedThisGame = hero.globalInfo.AstralAutomatonsSummonedThisGame ?? 0;\r\n\thero.globalInfo.BattlecriesTriggeredThisGame = hero.globalInfo.BattlecriesTriggeredThisGame ?? 0;\r\n\thero.globalInfo.DeathrattlesTriggeredThisGame = hero.globalInfo.DeathrattlesTriggeredThisGame ?? 0;\r\n\thero.globalInfo.BeetleAttackBuff = hero.globalInfo.BeetleAttackBuff ?? 0;\r\n\thero.globalInfo.BeetleHealthBuff = hero.globalInfo.BeetleHealthBuff ?? 0;\r\n\thero.globalInfo.ElementalAttackBuff = hero.globalInfo.ElementalAttackBuff ?? 0;\r\n\thero.globalInfo.ElementalHealthBuff = hero.globalInfo.ElementalHealthBuff ?? 0;\r\n\thero.globalInfo.PirateAttackBuff = hero.globalInfo.PirateAttackBuff ?? 0;\r\n\thero.globalInfo.PirateHealthBuff = hero.globalInfo.PirateHealthBuff ?? 0;\r\n\thero.globalInfo.TavernSpellAttackBuff = hero.globalInfo.TavernSpellAttackBuff ?? 0;\r\n\thero.globalInfo.TavernSpellHealthBuff = hero.globalInfo.TavernSpellHealthBuff ?? 0;\r\n\thero.globalInfo.MutatedLasherAttackBuff = hero.globalInfo.MutatedLasherAttackBuff ?? 0;\r\n\thero.globalInfo.MutatedLasherHealthBuff = hero.globalInfo.MutatedLasherHealthBuff ?? 0;\r\n\thero.globalInfo.TavernSpellsCastThisGame = hero.globalInfo.TavernSpellsCastThisGame ?? 0;\r\n\thero.globalInfo.TavernSpellsCastThisTurn = hero.globalInfo.TavernSpellsCastThisTurn ?? 0;\r\n\thero.globalInfo.CardsPlayedThisTurn = hero.globalInfo.CardsPlayedThisTurn ?? 0;\r\n\thero.globalInfo.MrrgltonsPlayedThisGame = hero.globalInfo.MrrgltonsPlayedThisGame ?? 0;\r\n\thero.globalInfo.AdditionalAttack = hero.globalInfo.AdditionalAttack ?? 0;\r\n\thero.globalInfo.SpellsCastThisGame = hero.globalInfo.SpellsCastThisGame ?? 0;\r\n\thero.globalInfo.UndeadAttackBonus = hero.globalInfo.UndeadAttackBonus ?? 0;\r\n\thero.globalInfo.UndeadHealthBonus = hero.globalInfo.UndeadHealthBonus ?? 0;\r\n\thero.globalInfo.HauntedCarapaceAttackBonus = hero.globalInfo.HauntedCarapaceAttackBonus ?? 0;\r\n\thero.globalInfo.HauntedCarapaceHealthBonus = hero.globalInfo.HauntedCarapaceHealthBonus ?? 0;\r\n\thero.globalInfo.FrostlingBonus = hero.globalInfo.FrostlingBonus ?? 0;\r\n\thero.globalInfo.BloodGemAttackBonus =\r\n\t\t(hero.globalInfo.BloodGemAttackBonus ?? 0) +\r\n\t\t// Not sure why, but this isn't reflected in the player enchant\r\n\t\t(hero.questRewardEntities?.filter((e) => e.cardId === CardIds.EndlessBloodMoon).length ?? 0);\r\n\thero.globalInfo.BloodGemHealthBonus =\r\n\t\t(hero.globalInfo.BloodGemHealthBonus ?? 0) +\r\n\t\t(hero.questRewardEntities?.filter((e) => e.cardId === CardIds.EndlessBloodMoon).length ?? 0);\r\n\thero.globalInfo.GoldrinnBuffAtk = hero.globalInfo.GoldrinnBuffAtk ?? 0;\r\n\thero.globalInfo.GoldrinnBuffHealth = hero.globalInfo.GoldrinnBuffHealth ?? 0;\r\n\thero.globalInfo.WhelpAttackBuff = hero.globalInfo.WhelpAttackBuff ?? 0;\r\n\thero.globalInfo.WhelpHealthBuff = hero.globalInfo.WhelpHealthBuff ?? 0;\r\n\thero.globalInfo.GoldSpentThisGame = hero.globalInfo.GoldSpentThisGame ?? 0;\r\n\thero.globalInfo.VolumizerAttackBuff = hero.globalInfo.VolumizerAttackBuff ?? 0;\r\n\thero.globalInfo.VolumizerHealthBuff = hero.globalInfo.VolumizerHealthBuff ?? 0;\r\n\thero.globalInfo.DeepBluesPlayed = hero.globalInfo.DeepBluesPlayed ?? 0;\r\n\thero.globalInfo.TastyLobstersBuff = hero.globalInfo.TastyLobstersBuff ?? 0;\r\n\thero.globalInfo.GoldenMinionsPlayedThisGame = hero.globalInfo.GoldenMinionsPlayedThisGame ?? 0;\r\n\thero.globalInfo.DeathrattlesTriggeredThisGame = hero.globalInfo.DeathrattlesTriggeredThisGame ?? 0;\r\n\thero.globalInfo.BackToBackCastThisGame = hero.globalInfo.BackToBackCastThisGame ?? 0;\r\n\thero.globalInfo.TavernSpellsCastThisTurn = hero.globalInfo.TavernSpellsCastThisTurn ?? 0;\r\n\thero.globalInfo.CardsPlayedThisTurn = hero.globalInfo.CardsPlayedThisTurn ?? 0;\r\n\thero.globalInfo.MrrgltonsPlayedThisGame = hero.globalInfo.MrrgltonsPlayedThisGame ?? 0;\r\n};\r\n\r\nexport const clearStealthIfNeeded = (\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\t// https://twitter.com/DCalkosz/status/1562194944688660481?s=20&t=100I8IVZmBKgYQWkdK8nIA\r\n\tif (board.every((entity) => entity.stealth && !entity.attack)) {\r\n\t\tboard.forEach((e) => updateStealth(e, false, board, hero, otherHero, gameState));\r\n\t}\r\n\tif (otherBoard.every((entity) => entity.stealth && !entity.attack)) {\r\n\t\totherBoard.forEach((e) => updateStealth(e, false, otherBoard, otherHero, hero, gameState));\r\n\t}\r\n\tif (board.every((e) => e.stealth) && otherBoard.every((e) => e.stealth)) {\r\n\t\tboard.forEach((e) => updateStealth(e, false, board, hero, otherHero, gameState));\r\n\t\totherBoard.forEach((e) => updateStealth(e, false, otherBoard, otherHero, hero, gameState));\r\n\t}\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"auras.js","sourceRoot":"","sources":["../../src/simulation/auras.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardsData } from '../cards/cards-data';\r\nimport { updateStealth } from '../keywords/stealth';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { addImpliedMechanics, hasCorrectTribe } from '../utils';\r\nimport { FullGameState } from './internal-game-state';\r\n\r\nexport const setMissingAuras = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): void => {\r\n\tsetMissingMinionsAura(board, boardHero, anomalies, allCards);\r\n\tsetMissingHeroPowerAura(board, boardHero);\r\n\tsetMissingTrinketAura(board, boardHero);\r\n};\r\n\r\nexport const setMissingTrinketAura = (board: BoardEntity[], boardHero: BgsPlayerEntity): void => {\r\n\tfor (const trinket of boardHero.trinkets ?? []) {\r\n\t\t// switch (trinket.cardId) {\r\n\t\t// \tcase CardIds.WindrunnerNecklace_BG30_MagicItem_997:\r\n\t\t// \tcase CardIds.WindrunnerNecklace_WindrunnerNecklaceToken_BG30_MagicItem_997t:\r\n\t\t// \t\tconst enchantment =\r\n\t\t// \t\t\ttrinket.cardId === CardIds.WindrunnerNecklace_BG30_MagicItem_997\r\n\t\t// \t\t\t\t? CardIds.WindrunnerNecklace_RunningLikeTheWindEnchantment_BG30_MagicItem_997e\r\n\t\t// \t\t\t\t: CardIds.WindrunnerNecklace_RunningLikeTheWindEnchantment_BG30_MagicItem_997e2;\r\n\t\t// \t\tconst buff = trinket.cardId === CardIds.WindrunnerNecklace_BG30_MagicItem_997 ? 8 : 20;\r\n\t\t// \t\tconst target = board[0];\r\n\t\t// \t\tif (!!target && !target.enchantments?.find((e) => e.cardId === enchantment)) {\r\n\t\t// \t\t\ttarget.attack += buff;\r\n\t\t// \t\t\ttarget.enchantments.push({\r\n\t\t// \t\t\t\tcardId: enchantment,\r\n\t\t// \t\t\t\toriginEntityId: trinket.entityId,\r\n\t\t// \t\t\t\ttiming: 0,\r\n\t\t// \t\t\t});\r\n\t\t// \t\t}\r\n\t\t// \t\tbreak;\r\n\t\t// }\r\n\t}\r\n};\r\n\r\nexport const setMissingHeroPowerAura = (board: BoardEntity[], boardHero: BgsPlayerEntity): void => {\r\n\tfor (const heroPower of boardHero.heroPowers) {\r\n\t\tif (heroPower.cardId === CardIds.TheSmokingGun) {\r\n\t\t\tboard\r\n\t\t\t\t.filter(\r\n\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t!e.enchantments.find(\r\n\t\t\t\t\t\t\t(ench) => ench.cardId === CardIds.TheSmokingGun_ArmedAndStillSmokingEnchantment,\r\n\t\t\t\t\t\t),\r\n\t\t\t\t)\r\n\t\t\t\t.forEach((e) => {\r\n\t\t\t\t\te.attack += 4;\r\n\t\t\t\t});\r\n\t\t}\r\n\t\tif (heroPower.cardId === CardIds.VolatileVenom) {\r\n\t\t\tboard\r\n\t\t\t\t.filter(\r\n\t\t\t\t\t(e) => !e.enchantments.find((ench) => ench.cardId === CardIds.VolatileVenom_VolatileEnchantment),\r\n\t\t\t\t)\r\n\t\t\t\t.forEach((e) => {\r\n\t\t\t\t\te.attack += 7;\r\n\t\t\t\t\te.health += 7;\r\n\t\t\t\t\te.enchantments.push({\r\n\t\t\t\t\t\tcardId: CardIds.VolatileVenom_VolatileEnchantment,\r\n\t\t\t\t\t\toriginEntityId: undefined,\r\n\t\t\t\t\t\ttiming: 0,\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\nconst setMissingMinionsAura = (\r\n\tboard: BoardEntity[],\r\n\tboardHero: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): void => {\r\n\tconst pirates: BoardEntity[] = [];\r\n\tconst murlocs: BoardEntity[] = [];\r\n\tconst undead: BoardEntity[] = [];\r\n\tconst divineShielded: BoardEntity[] = [];\r\n\tfor (const e of board) {\r\n\t\tif (e.divineShield) {\r\n\t\t\tdivineShielded.push(e);\r\n\t\t}\r\n\t\tif (hasCorrectTribe(e, boardHero, Race.PIRATE, anomalies, allCards)) {\r\n\t\t\tpirates.push(e);\r\n\t\t}\r\n\t\tif (hasCorrectTribe(e, boardHero, Race.MURLOC, anomalies, allCards)) {\r\n\t\t\tmurlocs.push(e);\r\n\t\t}\r\n\t\tif (hasCorrectTribe(e, boardHero, Race.UNDEAD, anomalies, allCards)) {\r\n\t\t\tundead.push(e);\r\n\t\t}\r\n\t}\r\n\tsetMissingAura(\r\n\t\tpirates,\r\n\t\tCardIds.SouthseaCaptainLegacy_BG_NEW1_027,\r\n\t\tCardIds.SouthseaCaptain_YarrrVanillaEnchantment,\r\n\t\t1,\r\n\t\t1,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tpirates,\r\n\t\tCardIds.SouthseaCaptainLegacy_TB_BaconUps_136,\r\n\t\tCardIds.SouthseaCaptain_YarrrEnchantment,\r\n\t\t2,\r\n\t\t2,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tmurlocs,\r\n\t\tCardIds.MurlocWarleaderLegacy_BG_EX1_507,\r\n\t\tCardIds.MurlocWarleader_MrgglaarglLegacyEnchantment,\r\n\t\t2,\r\n\t\t0,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tdivineShielded,\r\n\t\tCardIds.CyborgDrake_BG25_043,\r\n\t\tCardIds.CyborgDrake_CyborgEnhancementEnchantment_BG25_043e,\r\n\t\t6,\r\n\t\t0,\r\n\t\tfalse,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tundead,\r\n\t\tCardIds.SoreLoser_BG27_030,\r\n\t\tCardIds.SoreLoser_NoImWinningEnchantment_BG27_030e,\r\n\t\tboardHero.tavernTier,\r\n\t\t0,\r\n\t);\r\n\tsetMissingAura(\r\n\t\tundead,\r\n\t\tCardIds.SoreLoser_BG27_030_G,\r\n\t\tCardIds.SoreLoser_NoImWinningEnchantment_BG27_030e,\r\n\t\t2 * boardHero.tavernTier,\r\n\t\t0,\r\n\t);\r\n};\r\n\r\nconst setMissingAura = (\r\n\tboard: BoardEntity[],\r\n\tminionCardId: string,\r\n\tenchantmentCardId: string,\r\n\tattack: number,\r\n\thealth: number,\r\n\tignoreSelf = true,\r\n\tallCards: AllCardsService = null,\r\n): void => {\r\n\tconst buffers = board.filter((e) => e.cardId === minionCardId);\r\n\tfor (const buffer of buffers) {\r\n\t\tboard\r\n\t\t\t.filter((e) => !e.enchantments.find((ench) => ench.cardId === enchantmentCardId))\r\n\t\t\t.filter((e) => (ignoreSelf ? e.entityId !== buffer.entityId : true))\r\n\t\t\t.forEach((e) => {\r\n\t\t\t\te.attack += attack;\r\n\t\t\t\te.health += health;\r\n\t\t\t});\r\n\t}\r\n};\r\n\r\nexport const setImplicitDataHero = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tcardsData: CardsData,\r\n\tisPlayer: boolean,\r\n\tentityIdContainer: { entityId: number },\r\n): void => {\r\n\tfor (const heroPower of hero.heroPowers) {\r\n\t\tconst avengeValue = cardsData.avengeValue(heroPower.cardId);\r\n\t\tif (avengeValue > 0) {\r\n\t\t\theroPower.avengeCurrent = avengeValue - (heroPower.scoreValue2 ?? 0);\r\n\t\t\theroPower.avengeDefault = avengeValue;\r\n\t\t}\r\n\t\tif ((heroPower.info as BoardEntity)?.health) {\r\n\t\t\taddImpliedMechanics(heroPower.info as BoardEntity, cardsData);\r\n\t\t}\r\n\t}\r\n\t// Backward compatibility\r\n\tif (!!hero.questRewards?.length && !Array.isArray(hero.questRewards)) {\r\n\t\thero.questRewards = [hero.questRewards as any];\r\n\t}\r\n\r\n\t// Because Denathrius can send a quest reward as its hero power (I think)\r\n\t// For now deactivating this, until I have a scenario where this matters. It feels like\r\n\t// this should be a display issue only, as quest rewards are also handled in the code\r\n\tconst heroPowerAsReward = null; // hero.cardId === CardIds.SireDenathrius_BG24_HERO_100 ? hero.heroPowers[0]?.cardId : null;\r\n\thero.questRewards = [...(hero.questRewards ?? []), heroPowerAsReward].filter((e) => !!e);\r\n\thero.questRewardEntities = hero.questRewardEntities\r\n\t\t? hero.questRewardEntities.map((reward: any) => ({\r\n\t\t\t\tcardId: reward.CardId,\r\n\t\t\t\tscriptDataNum1: reward.ScriptDataNum1 ?? 0,\r\n\t\t\t\tentityId: entityIdContainer.entityId--,\r\n\t\t\t\tavengeDefault: cardsData.avengeValue(reward.CardId),\r\n\t\t\t\tavengeCurrent: cardsData.avengeValue(reward.CardId),\r\n\t\t }))\r\n\t\t: hero.questRewards.map((reward) => ({\r\n\t\t\t\tcardId: reward,\r\n\t\t\t\tentityId: entityIdContainer.entityId--,\r\n\t\t\t\tavengeCurrent: cardsData.avengeValue(reward),\r\n\t\t\t\tavengeDefault: cardsData.avengeValue(reward),\r\n\t\t\t\tscriptDataNum1: cardsData.defaultScriptDataNum(reward),\r\n\t\t }));\r\n\thero.trinkets = (hero.trinkets ?? [])\r\n\t\t.map((trinket) => ({\r\n\t\t\t...trinket,\r\n\t\t\tavengeDefault: cardsData.avengeValue(trinket.cardId),\r\n\t\t\tavengeCurrent: cardsData.avengeValue(trinket.cardId),\r\n\t\t\t// Use scriptDataNum1 to keep the info from the input\r\n\t\t\t// We don't want to use the default value is the value from the game state is 0\r\n\t\t\t// In that case, we probably want to use the ChargesLeft mechanism\r\n\t\t\tscriptDataNum1: trinket.scriptDataNum1 ?? cardsData.defaultScriptDataNum(trinket.cardId),\r\n\t\t}))\r\n\t\t.sort((a, b) => a.entityId - b.entityId);\r\n\t// 0 is not a valid entityId\r\n\thero.entityId = hero.entityId || entityIdContainer.entityId--;\r\n\thero.hand = hero.hand ?? [];\r\n\thero.enchantments = hero.enchantments ?? [];\r\n\tif (!hero.globalInfo) {\r\n\t\thero.globalInfo = {};\r\n\t}\r\n\r\n\thero.globalInfo.PirateAttackBonus = hero.globalInfo.PirateAttackBonus ?? 0;\r\n\thero.globalInfo.MechAttackBonus = hero.globalInfo.MechAttackBonus ?? 0;\r\n\thero.globalInfo.EternalKnightsDeadThisGame = hero.globalInfo.EternalKnightsDeadThisGame ?? 0;\r\n\thero.globalInfo.EternalKnightAttackBuff = hero.globalInfo.EternalKnightAttackBuff ?? 0;\r\n\thero.globalInfo.EternalKnightHealthBuff = hero.globalInfo.EternalKnightHealthBuff ?? 0;\r\n\thero.globalInfo.SanlaynScribesDeadThisGame = hero.globalInfo.SanlaynScribesDeadThisGame ?? 0;\r\n\thero.globalInfo.BeastsSummonedThisGame = hero.globalInfo.BeastsSummonedThisGame ?? 0;\r\n\thero.globalInfo.BeastsSummonedThisCombat = hero.globalInfo.BeastsSummonedThisCombat ?? 0;\r\n\thero.globalInfo.MagnetizedThisGame = hero.globalInfo.MagnetizedThisGame ?? 0;\r\n\thero.globalInfo.PiratesSummonedThisGame = hero.globalInfo.PiratesSummonedThisGame ?? 0;\r\n\thero.globalInfo.AstralAutomatonsSummonedThisGame = hero.globalInfo.AstralAutomatonsSummonedThisGame ?? 0;\r\n\thero.globalInfo.BattlecriesTriggeredThisGame = hero.globalInfo.BattlecriesTriggeredThisGame ?? 0;\r\n\thero.globalInfo.DeathrattlesTriggeredThisGame = hero.globalInfo.DeathrattlesTriggeredThisGame ?? 0;\r\n\thero.globalInfo.BeetleAttackBuff = hero.globalInfo.BeetleAttackBuff ?? 0;\r\n\thero.globalInfo.BeetleHealthBuff = hero.globalInfo.BeetleHealthBuff ?? 0;\r\n\thero.globalInfo.ElementalAttackBuff = hero.globalInfo.ElementalAttackBuff ?? 0;\r\n\thero.globalInfo.ElementalHealthBuff = hero.globalInfo.ElementalHealthBuff ?? 0;\r\n\thero.globalInfo.PirateAttackBuff = hero.globalInfo.PirateAttackBuff ?? 0;\r\n\thero.globalInfo.PirateHealthBuff = hero.globalInfo.PirateHealthBuff ?? 0;\r\n\thero.globalInfo.TavernSpellAttackBuff = hero.globalInfo.TavernSpellAttackBuff ?? 0;\r\n\thero.globalInfo.TavernSpellHealthBuff = hero.globalInfo.TavernSpellHealthBuff ?? 0;\r\n\thero.globalInfo.MutatedLasherAttackBuff = hero.globalInfo.MutatedLasherAttackBuff ?? 0;\r\n\thero.globalInfo.MutatedLasherHealthBuff = hero.globalInfo.MutatedLasherHealthBuff ?? 0;\r\n\thero.globalInfo.TavernSpellsCastThisGame = hero.globalInfo.TavernSpellsCastThisGame ?? 0;\r\n\thero.globalInfo.TavernSpellsCastThisTurn = hero.globalInfo.TavernSpellsCastThisTurn ?? 0;\r\n\thero.globalInfo.CardsPlayedThisTurn = hero.globalInfo.CardsPlayedThisTurn ?? 0;\r\n\thero.globalInfo.MrrgltonsPlayedThisGame = hero.globalInfo.MrrgltonsPlayedThisGame ?? 0;\r\n\thero.globalInfo.AdditionalAttack = hero.globalInfo.AdditionalAttack ?? 0;\r\n\thero.globalInfo.SpellsCastThisGame = hero.globalInfo.SpellsCastThisGame ?? 0;\r\n\thero.globalInfo.UndeadAttackBonus = hero.globalInfo.UndeadAttackBonus ?? 0;\r\n\thero.globalInfo.UndeadHealthBonus = hero.globalInfo.UndeadHealthBonus ?? 0;\r\n\thero.globalInfo.HauntedCarapaceAttackBonus = hero.globalInfo.HauntedCarapaceAttackBonus ?? 0;\r\n\thero.globalInfo.HauntedCarapaceHealthBonus = hero.globalInfo.HauntedCarapaceHealthBonus ?? 0;\r\n\thero.globalInfo.FrostlingBonus = hero.globalInfo.FrostlingBonus ?? 0;\r\n\thero.globalInfo.BloodGemAttackBonus =\r\n\t\t(hero.globalInfo.BloodGemAttackBonus ?? 0) +\r\n\t\t// Not sure why, but this isn't reflected in the player enchant\r\n\t\t(hero.questRewardEntities?.filter((e) => e.cardId === CardIds.EndlessBloodMoon).length ?? 0);\r\n\thero.globalInfo.BloodGemHealthBonus =\r\n\t\t(hero.globalInfo.BloodGemHealthBonus ?? 0) +\r\n\t\t(hero.questRewardEntities?.filter((e) => e.cardId === CardIds.EndlessBloodMoon).length ?? 0);\r\n\thero.globalInfo.GoldrinnBuffAtk = hero.globalInfo.GoldrinnBuffAtk ?? 0;\r\n\thero.globalInfo.GoldrinnBuffHealth = hero.globalInfo.GoldrinnBuffHealth ?? 0;\r\n\thero.globalInfo.WhelpAttackBuff = hero.globalInfo.WhelpAttackBuff ?? 0;\r\n\thero.globalInfo.WhelpHealthBuff = hero.globalInfo.WhelpHealthBuff ?? 0;\r\n\thero.globalInfo.GoldSpentThisGame = hero.globalInfo.GoldSpentThisGame ?? 0;\r\n\thero.globalInfo.VolumizerAttackBuff = hero.globalInfo.VolumizerAttackBuff ?? 0;\r\n\thero.globalInfo.VolumizerHealthBuff = hero.globalInfo.VolumizerHealthBuff ?? 0;\r\n\thero.globalInfo.DeepBluesPlayed = hero.globalInfo.DeepBluesPlayed ?? 0;\r\n\thero.globalInfo.GoldenMinionsPlayedThisGame = hero.globalInfo.GoldenMinionsPlayedThisGame ?? 0;\r\n\thero.globalInfo.DeathrattlesTriggeredThisGame = hero.globalInfo.DeathrattlesTriggeredThisGame ?? 0;\r\n\thero.globalInfo.BackToBackCastThisGame = hero.globalInfo.BackToBackCastThisGame ?? 0;\r\n\thero.globalInfo.TavernSpellsCastThisTurn = hero.globalInfo.TavernSpellsCastThisTurn ?? 0;\r\n\thero.globalInfo.CardsPlayedThisTurn = hero.globalInfo.CardsPlayedThisTurn ?? 0;\r\n\thero.globalInfo.MrrgltonsPlayedThisGame = hero.globalInfo.MrrgltonsPlayedThisGame ?? 0;\r\n\thero.globalInfo.TastyLobstersBuff = hero.globalInfo.TastyLobstersBuff ?? 0;\r\n\t// For some reason the info was not transmitted correctly, so we take the highest value\r\n\t// from the board entities\r\n\t// Won't be totally exact if the value is odd, but should be close enough for a fallback\r\n\tif (hero.globalInfo.TastyLobstersBuff === 0) {\r\n\t\thero.globalInfo.TastyLobstersBuff = board\r\n\t\t\t.filter((e) => e.cardId === CardIds.TastyLobster_BG36_202 || e.cardId === CardIds.TastyLobster_BG36_202_G)\r\n\t\t\t.map((e) => {\r\n\t\t\t\tconst rawScript = e.scriptDataNum1 ?? 0;\r\n\t\t\t\tconst baseValue = e.cardId === CardIds.TastyLobster_BG36_202 ? rawScript : rawScript / 2;\r\n\t\t\t\treturn baseValue;\r\n\t\t\t})\r\n\t\t\t.reduce((max, value) => Math.max(max, value), 0);\r\n\t}\r\n};\r\n\r\nexport const clearStealthIfNeeded = (\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\t// https://twitter.com/DCalkosz/status/1562194944688660481?s=20&t=100I8IVZmBKgYQWkdK8nIA\r\n\tif (board.every((entity) => entity.stealth && !entity.attack)) {\r\n\t\tboard.forEach((e) => updateStealth(e, false, board, hero, otherHero, gameState));\r\n\t}\r\n\tif (otherBoard.every((entity) => entity.stealth && !entity.attack)) {\r\n\t\totherBoard.forEach((e) => updateStealth(e, false, otherBoard, otherHero, hero, gameState));\r\n\t}\r\n\tif (board.every((e) => e.stealth) && otherBoard.every((e) => e.stealth)) {\r\n\t\tboard.forEach((e) => updateStealth(e, false, board, hero, otherHero, gameState));\r\n\t\totherBoard.forEach((e) => updateStealth(e, false, otherBoard, otherHero, hero, gameState));\r\n\t}\r\n};\r\n"]}
|
|
@@ -51,15 +51,18 @@ const getValidDeathrattles = (board, hero, gameState) => {
|
|
|
51
51
|
};
|
|
52
52
|
exports.getValidDeathrattles = getValidDeathrattles;
|
|
53
53
|
const hasValidDeathrattle = (entity, hero, gameState) => {
|
|
54
|
-
var _a, _b;
|
|
54
|
+
var _a, _b, _c;
|
|
55
55
|
if ((0, utils_1.hasEntityMechanic)(entity, reference_data_1.GameTag.DEATHRATTLE, gameState.allCards)) {
|
|
56
56
|
return true;
|
|
57
57
|
}
|
|
58
|
-
if ((
|
|
58
|
+
if ((_a = entity.rememberedDeathrattles) === null || _a === void 0 ? void 0 : _a.length) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
if (((_b = hero.trinkets) === null || _b === void 0 ? void 0 : _b.some((t) => t.cardId === "BG32_MagicItem_830")) &&
|
|
59
62
|
(entity.cardId === "BG25_041" || entity.cardId === "BG25_041_G")) {
|
|
60
63
|
return true;
|
|
61
64
|
}
|
|
62
|
-
if ((
|
|
65
|
+
if ((_c = entity.rememberedDeathrattles) === null || _c === void 0 ? void 0 : _c.length) {
|
|
63
66
|
return true;
|
|
64
67
|
}
|
|
65
68
|
if (entity.enchantments &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deathrattle-utils.js","sourceRoot":"","sources":["../../src/simulation/deathrattle-utils.ts"],"names":[],"mappings":";;;AAAA,iEAAuD;AAGvD,4DAAyE;AACzE,iEAA4D;AAE5D,oCAA6C;AAG7C,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAS;;;;;;;;;;;;;;;;;;;;;;CAsBtD,CAAC,CAAC;AACH,IAAI,6BAA0C,CAAC;AAExC,MAAM,6BAA6B,GAAG,CAAC,MAAc,EAAW,EAAE;IACxE,IAAI,8BAA8B,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QAC/C,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,CAAC,6BAA6B,EAAE;QACnC,6BAA6B,GAAG,IAAI,GAAG,EAAU,CAAC;QAClD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,6BAAY,CAAC,EAAE;YACnD,IAAI,IAAA,+CAA8B,EAAC,QAAQ,CAAC,EAAE;gBAC7C,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,OAAO,EAAE;oBAC5C,6BAA6B,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;iBAChD;aACD;SACD;KACD;IACD,OAAO,6BAA6B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC,CAAC;AAfW,QAAA,6BAA6B,iCAexC;AAEK,MAAM,oBAAoB,GAAG,CACnC,KAAoB,EACpB,IAAqB,EACrB,SAAwB,EACR,EAAE;IAClB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,2BAAmB,EAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC;AANW,QAAA,oBAAoB,wBAM/B;AAEK,MAAM,mBAAmB,GAAG,CAAC,MAAmB,EAAE,IAAqB,EAAE,SAAwB,EAAW,EAAE;;IACpH,IAAI,IAAA,yBAAiB,EAAC,MAAM,EAAE,wBAAO,CAAC,WAAW,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;QACvE,OAAO,IAAI,CAAC;KACZ;IACD,IACC,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAAkD,CAAC;QACtF,CAAC,MAAM,CAAC,MAAM,eAAgC,IAAI,MAAM,CAAC,MAAM,iBAAkC,CAAC,EACjG;QACD,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,MAAA,MAAM,CAAC,sBAAsB,0CAAE,MAAM,EAAE;QAC1C,OAAO,IAAI,CAAC;KACZ;IACD,IACC,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAA,qCAA6B,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAC3F;QACD,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"deathrattle-utils.js","sourceRoot":"","sources":["../../src/simulation/deathrattle-utils.ts"],"names":[],"mappings":";;;AAAA,iEAAuD;AAGvD,4DAAyE;AACzE,iEAA4D;AAE5D,oCAA6C;AAG7C,MAAM,8BAA8B,GAAG,IAAI,GAAG,CAAS;;;;;;;;;;;;;;;;;;;;;;CAsBtD,CAAC,CAAC;AACH,IAAI,6BAA0C,CAAC;AAExC,MAAM,6BAA6B,GAAG,CAAC,MAAc,EAAW,EAAE;IACxE,IAAI,8BAA8B,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QAC/C,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,CAAC,6BAA6B,EAAE;QACnC,6BAA6B,GAAG,IAAI,GAAG,EAAU,CAAC;QAClD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,6BAAY,CAAC,EAAE;YACnD,IAAI,IAAA,+CAA8B,EAAC,QAAQ,CAAC,EAAE;gBAC7C,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,OAAO,EAAE;oBAC5C,6BAA6B,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;iBAChD;aACD;SACD;KACD;IACD,OAAO,6BAA6B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAClD,CAAC,CAAC;AAfW,QAAA,6BAA6B,iCAexC;AAEK,MAAM,oBAAoB,GAAG,CACnC,KAAoB,EACpB,IAAqB,EACrB,SAAwB,EACR,EAAE;IAClB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,2BAAmB,EAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC;AANW,QAAA,oBAAoB,wBAM/B;AAEK,MAAM,mBAAmB,GAAG,CAAC,MAAmB,EAAE,IAAqB,EAAE,SAAwB,EAAW,EAAE;;IACpH,IAAI,IAAA,yBAAiB,EAAC,MAAM,EAAE,wBAAO,CAAC,WAAW,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;QACvE,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,MAAA,MAAM,CAAC,sBAAsB,0CAAE,MAAM,EAAE;QAC1C,OAAO,IAAI,CAAC;KACZ;IACD,IACC,CAAA,MAAA,IAAI,CAAC,QAAQ,0CAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAAkD,CAAC;QACtF,CAAC,MAAM,CAAC,MAAM,eAAgC,IAAI,MAAM,CAAC,MAAM,iBAAkC,CAAC,EACjG;QACD,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,MAAA,MAAM,CAAC,sBAAsB,0CAAE,MAAM,EAAE;QAC1C,OAAO,IAAI,CAAC;KACZ;IACD,IACC,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAA,qCAA6B,EAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAC3F;QACD,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAvBW,QAAA,mBAAmB,uBAuB9B","sourcesContent":["import { GameTag } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasDeathrattleSpawnEnchantment } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { hasEntityMechanic } from '../utils';\r\nimport { FullGameState } from './internal-game-state';\r\n\r\nconst VALID_DEATHRATTLE_ENCHANTMENTS = new Set<string>([\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,\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment,\r\n\tCardIds.LightningInvocation,\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\nlet mappedDeathrattleEnchantments: Set<string>;\r\n\r\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\r\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.has(cardId)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (!mappedDeathrattleEnchantments) {\r\n\t\tmappedDeathrattleEnchantments = new Set<string>();\r\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\r\n\t\t\tif (hasDeathrattleSpawnEnchantment(cardImpl)) {\r\n\t\t\t\tfor (const mappedCardId of cardImpl.cardIds) {\r\n\t\t\t\t\tmappedDeathrattleEnchantments.add(mappedCardId);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn mappedDeathrattleEnchantments.has(cardId);\r\n};\r\n\r\nexport const getValidDeathrattles = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): BoardEntity[] => {\r\n\treturn board.filter((entity) => hasValidDeathrattle(entity, hero, gameState));\r\n};\r\n\r\nexport const hasValidDeathrattle = (entity: BoardEntity, hero: BgsPlayerEntity, gameState: FullGameState): boolean => {\r\n\tif (hasEntityMechanic(entity, GameTag.DEATHRATTLE, gameState.allCards)) {\r\n\t\treturn true;\r\n\t}\r\n\tif (entity.rememberedDeathrattles?.length) {\r\n\t\treturn true;\r\n\t}\r\n\tif (\r\n\t\thero.trinkets?.some((t) => t.cardId === CardIds.FelementalPortrait_BG32_MagicItem_830) &&\r\n\t\t(entity.cardId === CardIds.Felemental_BG25_041 || entity.cardId === CardIds.Felemental_BG25_041_G)\r\n\t) {\r\n\t\treturn true;\r\n\t}\r\n\tif (entity.rememberedDeathrattles?.length) {\r\n\t\treturn true;\r\n\t}\r\n\tif (\r\n\t\tentity.enchantments &&\r\n\t\tentity.enchantments.some((enchantment) => isValidDeathrattleEnchantment(enchantment.cardId))\r\n\t) {\r\n\t\treturn true;\r\n\t}\r\n\treturn false;\r\n};\r\n"]}
|
package/dist/utils.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export declare const stringifySimpleCard: (entity: BoardEntity, allCards?: AllCa
|
|
|
38
38
|
export declare const isFish: (entity: BoardEntity) => boolean;
|
|
39
39
|
export declare const isPilotedWhirlOTron: (entity: BoardEntity) => boolean;
|
|
40
40
|
export declare const isGolden: (cardId: string, allCards: AllCardsService) => boolean;
|
|
41
|
-
export declare const isBoardEntity: (entity: BoardEntity | BoardTrinket) => entity is BoardEntity;
|
|
41
|
+
export declare const isBoardEntity: (entity: BoardEntity | BoardTrinket | BgsPlayerEntity) => entity is BoardEntity;
|
|
42
42
|
export declare const getPlayerState: (gameState: GameState, hero: BgsPlayerEntity) => PlayerState;
|
|
43
43
|
export declare const getTeammateInitialState: (gameState: GameState, hero: BgsPlayerEntity) => PlayerState;
|
|
44
44
|
export declare const getTeamInitialStates: (gameState: GameState, hero: BgsPlayerEntity) => PlayerState[];
|
package/dist/utils.js
CHANGED
|
@@ -465,7 +465,11 @@ const addImpliedMechanics = (entity, cardsData) => {
|
|
|
465
465
|
entity.abiityChargesLeft = defaultChargesImpl.defaultCharges(entity);
|
|
466
466
|
}
|
|
467
467
|
else {
|
|
468
|
-
entity.abiityChargesLeft = THREE_CHARGES_IDS.has(entity.cardId)
|
|
468
|
+
entity.abiityChargesLeft = THREE_CHARGES_IDS.has(entity.cardId)
|
|
469
|
+
? 3
|
|
470
|
+
: TWO_CHARGES_IDS.has(entity.cardId)
|
|
471
|
+
? 2
|
|
472
|
+
: 1;
|
|
469
473
|
}
|
|
470
474
|
return setImplicitDataForEntity(entity, cardsData);
|
|
471
475
|
};
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { ALL_BG_RACES, AllCardsService, GameTag, Race, ReferenceCard, SpellSchool } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity, BoardTrinket } from './bgs-player-entity';\r\nimport { BoardEnchantment, BoardEntity } from './board-entity';\r\nimport { BoardSecret } from './board-secret';\r\nimport { hasDefaultCharges } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { extraHits } from './cards/impl/enchantments/toreths-blessing';\r\nimport { CardIds } from './services/card-ids';\r\nimport { pickRandom, shuffleArray } from './services/utils';\r\nimport { FullGameState, GameState, PlayerState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { modifyStats } from './simulation/stats';\r\n\r\nconst CLEAVE_IDS = new Set<string>([\r\n\tCardIds.CaveHydra_BG_LOOT_078,\r\n\tCardIds.CaveHydra_TB_BaconUps_151,\r\n\tCardIds.FoeReaper4000_BG_GVG_113,\r\n\tCardIds.FoeReaper4000_TB_BaconUps_153,\r\n\tCardIds.BladeCollector_BG26_817,\r\n\tCardIds.BladeCollector_BG26_817_G,\r\n\tCardIds.KerriganQueenOfBlades_UltraliskToken_BG31_HERO_811t10,\r\n\tCardIds.Ultralisk_BG31_HERO_811t10_G,\r\n\tCardIds.TimewarpedUltralisk_BG34_Treasure_994,\r\n\tCardIds.TimewarpedUltralisk_BG34_Treasure_994_G,\r\n\tCardIds.TimewarpedCollector_BG34_Giant_680,\r\n\tCardIds.TimewarpedCollector_BG34_Giant_680_G,\r\n]);\r\nconst ATTACK_IMMEDIATELY_IDS = [\r\n\tCardIds.Scallywag_SkyPirateToken_BGS_061t,\r\n\tCardIds.Scallywag_SkyPirateToken_TB_BaconUps_141t,\r\n\tCardIds.Onyxia_OnyxianWhelpToken,\r\n\tCardIds.TwilightWhelp_WhelpToken,\r\n\tCardIds.TwilightHatchling_TwilightWhelpToken_BG34_630t,\r\n\tCardIds.TwilightHatchling_TwilightWhelpToken_BG34_630_Gt,\r\n\t// CardIds.Carrier_InterceptorToken_BG31_HERO_802pt1t,\r\n\t// CardIds.Interceptor_BG31_HERO_802pt1t_G,\r\n\t// The token doesn't attack immediately natively, only when spawned by the spell\r\n\t// See http://replays.firestoneapp.com/?reviewId=8924452a-540a-4324-8306-46900c3f9f35&turn=22&action=38\r\n\t// CardIds.ToxicTumbleweed_TumblingAssassinToken_BG28_641t,\r\n];\r\nconst CANT_ATTACK_IDS = new Set<string>([\r\n\t// CardIds.ArcaneCannon_BGS_077, CardIds.ArcaneCannon_TB_BaconUps_128\r\n]);\r\n\r\nexport const buildSingleBoardEntity = (\r\n\tcardId: string,\r\n\tcontrollerHero: BgsPlayerEntity,\r\n\tfriendlyBoard: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tfriendly: boolean,\r\n\tentityId = 1,\r\n\tspawnReborn = false,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tentityToSpawn: BoardEntity,\r\n\toriginalEntity: BoardEntity = null,\r\n\toptions: {\r\n\t\treferenceCardToUse: ReferenceCard;\r\n\t} = null,\r\n): BoardEntity => {\r\n\tconst trueRefCard = allCards.getCard(cardId);\r\n\tconst card = options?.referenceCardToUse ?? trueRefCard;\r\n\tconst attackImmediately = ATTACK_IMMEDIATELY_IDS.indexOf(cardId as CardIds) !== -1;\r\n\tconst newEntity = !!entityToSpawn\r\n\t\t? ({\r\n\t\t\t\t...entityToSpawn,\r\n\t\t\t\tentityId: sharedState.currentEntityId++,\r\n\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\tavengeCurrent: entityToSpawn.avengeDefault,\r\n\t\t\t\t// attacking: false,\r\n\t\t\t\tdamageMultiplier: 1,\r\n\t\t\t\tfrenzyChargesLeft: 1,\r\n\t\t\t\tfriendly: friendly,\r\n\t\t\t\thasAttacked: undefined,\r\n\t\t } as BoardEntity)\r\n\t\t: addImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\tentityId: entityId,\r\n\t\t\t\t\tattack: card.attack,\r\n\t\t\t\t\thasAttacked: undefined,\r\n\t\t\t\t\tcardId: cardId,\r\n\t\t\t\t\tdivineShield: hasMechanic(card, GameTag.DIVINE_SHIELD),\r\n\t\t\t\t\thealth: card.health,\r\n\t\t\t\t\tmaxHealth: card.health || trueRefCard.health,\r\n\t\t\t\t\tmaxAttack: card.attack || trueRefCard.attack,\r\n\t\t\t\t\ttaunt: hasMechanic(card, GameTag.TAUNT),\r\n\t\t\t\t\treborn: hasMechanic(card, GameTag.REBORN),\r\n\t\t\t\t\tpoisonous: hasMechanic(card, GameTag.POISONOUS),\r\n\t\t\t\t\tvenomous: hasMechanic(card, GameTag.VENOMOUS),\r\n\t\t\t\t\tstealth: hasMechanic(card, GameTag.STEALTH),\r\n\t\t\t\t\twindfury: hasMechanic(card, GameTag.WINDFURY),\r\n\t\t\t\t\tenchantments: [],\r\n\t\t\t\t\tpendingAttackBuffs: [],\r\n\t\t\t\t\tfriendly: friendly,\r\n\t\t\t\t\tattackImmediately: attackImmediately,\r\n\t\t\t\t\tavengeCurrent: cardsData.avengeValue(cardId),\r\n\t\t\t\t\tavengeDefault: cardsData.avengeValue(cardId),\r\n\t\t\t\t\tscriptDataNum1: originalEntity?.scriptDataNum1 ?? 0,\r\n\t\t\t\t\t// This is useful for Showy Cycilst, but I wonder if this could cause some issues otherwise\r\n\t\t\t\t\tscriptDataNum2: originalEntity?.scriptDataNum2 ?? 0,\r\n\t\t\t\t} as BoardEntity,\r\n\t\t\t\tcardsData,\r\n\t\t );\r\n\r\n\tif (spawnReborn && !entityToSpawn) {\r\n\t\tif (cardId === CardIds.BuildAnUndead_PutricidesCreationToken) {\r\n\t\t\tconst stitchedCardId = !!originalEntity.additionalCards?.length ? originalEntity.additionalCards[0] : null;\r\n\t\t\tif (stitchedCardId) {\r\n\t\t\t\tconst stitchedCard = allCards.getCard(stitchedCardId);\r\n\t\t\t\tnewEntity.attack = newEntity.attack + stitchedCard.attack;\r\n\t\t\t\tnewEntity.maxHealth = newEntity.maxHealth + stitchedCard.health;\r\n\t\t\t\tnewEntity.taunt = newEntity.taunt || hasMechanic(stitchedCard, GameTag.TAUNT);\r\n\t\t\t\tnewEntity.divineShield = newEntity.divineShield || hasMechanic(stitchedCard, GameTag.DIVINE_SHIELD);\r\n\t\t\t\tnewEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;\r\n\t\t\t\tnewEntity.poisonous = newEntity.poisonous || hasMechanic(stitchedCard, GameTag.POISONOUS);\r\n\t\t\t\tnewEntity.venomous = newEntity.venomous || hasMechanic(stitchedCard, GameTag.VENOMOUS);\r\n\t\t\t\tnewEntity.windfury = newEntity.windfury || hasMechanic(stitchedCard, GameTag.WINDFURY);\r\n\t\t\t\tnewEntity.avengeCurrent = newEntity.avengeCurrent || cardsData.avengeValue(stitchedCardId);\r\n\t\t\t\tnewEntity.avengeDefault = newEntity.avengeDefault || cardsData.avengeValue(stitchedCardId);\r\n\t\t\t}\r\n\t\t} else if (\r\n\t\t\tcardId === CardIds.ZilliaxAssembled_BG29_100_G &&\r\n\t\t\t!!originalEntity.additionalCards?.filter((c) => !!c).length\r\n\t\t) {\r\n\t\t\t// In this case, the base stats are still correct (the golden stats of Zilliax), but the keywords\r\n\t\t\t// can change\r\n\t\t\tfor (const moduleCardId of originalEntity.additionalCards) {\r\n\t\t\t\tconst moduleCard = allCards.getCard(moduleCardId);\r\n\t\t\t\tnewEntity.taunt = newEntity.taunt || hasMechanic(moduleCard, GameTag.TAUNT);\r\n\t\t\t\tnewEntity.divineShield = newEntity.divineShield || hasMechanic(moduleCard, GameTag.DIVINE_SHIELD);\r\n\t\t\t\tnewEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;\r\n\t\t\t\tnewEntity.poisonous = newEntity.poisonous || hasMechanic(moduleCard, GameTag.POISONOUS);\r\n\t\t\t\tnewEntity.venomous = newEntity.venomous || hasMechanic(moduleCard, GameTag.VENOMOUS);\r\n\t\t\t\tnewEntity.windfury = newEntity.windfury || hasMechanic(moduleCard, GameTag.WINDFURY);\r\n\t\t\t\tnewEntity.stealth = newEntity.stealth || hasMechanic(moduleCard, GameTag.STEALTH);\r\n\t\t\t}\r\n\t\t}\r\n\t\tnewEntity.health = 1;\r\n\t\tnewEntity.reborn = false;\r\n\t\tnewEntity.scriptDataNum1 = getScriptDataNum1(cardId, originalEntity);\r\n\r\n\t\t// For ghoul-acabra + reborn\r\n\t\t// newEntity.attack += originalEntity.permanentAttack ?? 0;\r\n\t\t// newEntity.health += originalEntity.permanentHealth ?? 0;\r\n\t}\r\n\r\n\tnewEntity.hadDivineShield = newEntity.divineShield || newEntity.hadDivineShield;\r\n\treturn newEntity;\r\n};\r\n\r\nconst getScriptDataNum1 = (cardId: string, originalEntity: BoardEntity): number => {\r\n\tswitch (cardId) {\r\n\t\tcase CardIds.OctosariWrapGod_BG26_804:\r\n\t\t\treturn 8;\r\n\t\tcase CardIds.OctosariWrapGod_BG26_804_G:\r\n\t\t\treturn 16;\r\n\t\tdefault:\r\n\t\t\treturn 0;\r\n\t}\r\n};\r\n\r\nexport const buildRandomUndeadCreation = (\r\n\tcontrollerHero: BgsPlayerEntity,\r\n\tfriendlyBoard: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tfriendly: boolean,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n): BoardEntity => {\r\n\tconst baseCard = pickRandom(cardsData.putricidePool1);\r\n\tconst newEntity = buildSingleBoardEntity(\r\n\t\tbaseCard,\r\n\t\tcontrollerHero,\r\n\t\tfriendlyBoard,\r\n\t\tallCards,\r\n\t\tfriendly,\r\n\t\tsharedState.currentEntityId++,\r\n\t\tfalse,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tnull,\r\n\t);\r\n\r\n\tconst stitchedCardId =\r\n\t\tbaseCard === CardIds.EternalSummoner_BG25_009\r\n\t\t\t? pickRandom(cardsData.putridicePool2ForEternalSummoner)\r\n\t\t\t: pickRandom(cardsData.putricidePool2);\r\n\tconst stitchedCard = allCards.getCard(stitchedCardId);\r\n\tnewEntity.attack += stitchedCard.attack;\r\n\tnewEntity.health += stitchedCard.health;\r\n\tnewEntity.maxHealth = (newEntity.maxHealth ?? newEntity.health) + stitchedCard.health;\r\n\tnewEntity.maxAttack = (newEntity.maxAttack ?? newEntity.attack - stitchedCard.attack) + stitchedCard.attack;\r\n\tnewEntity.taunt = newEntity.taunt || hasMechanic(stitchedCard, GameTag.TAUNT);\r\n\tnewEntity.divineShield = newEntity.divineShield || hasMechanic(stitchedCard, GameTag.DIVINE_SHIELD);\r\n\tnewEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;\r\n\tnewEntity.poisonous = newEntity.poisonous || hasMechanic(stitchedCard, GameTag.POISONOUS);\r\n\tnewEntity.venomous = newEntity.venomous || hasMechanic(stitchedCard, GameTag.VENOMOUS);\r\n\tnewEntity.windfury = newEntity.windfury || hasMechanic(stitchedCard, GameTag.WINDFURY);\r\n\tnewEntity.reborn = newEntity.reborn || hasMechanic(stitchedCard, GameTag.REBORN);\r\n\tnewEntity.avengeCurrent = newEntity.avengeCurrent || cardsData.avengeValue(stitchedCardId);\r\n\tnewEntity.avengeDefault = newEntity.avengeDefault || cardsData.avengeValue(stitchedCardId);\r\n\tnewEntity.additionalCards = [stitchedCardId];\r\n\treturn newEntity;\r\n};\r\n\r\nexport const grantRandomAttack = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tadditionalAttack: number,\r\n\tgameState: FullGameState,\r\n\texcludeSource = false,\r\n): void => {\r\n\tconst candidateBoard = board\r\n\t\t.filter((e) => !excludeSource || e.entityId !== source.entityId)\r\n\t\t.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tif (candidateBoard.length > 0) {\r\n\t\tconst target = candidateBoard[Math.floor(Math.random() * candidateBoard.length)];\r\n\t\tmodifyStats(target, source, additionalAttack, 0, candidateBoard, hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const grantRandomHealth = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\texcludeSource = false,\r\n): void => {\r\n\tconst candidateBoard = board\r\n\t\t.filter((e) => !excludeSource || e.entityId !== source.entityId)\r\n\t\t.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tif (candidateBoard.length > 0) {\r\n\t\tconst target = pickRandom(candidateBoard);\r\n\t\tmodifyStats(target, source, 0, health, board, hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const grantRandomStats = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\trace: Race,\r\n\texcludeSource: boolean,\r\n\tgameState: FullGameState,\r\n): BoardEntity => {\r\n\tif (board.length > 0) {\r\n\t\tconst target: BoardEntity = getRandomAliveMinion(\r\n\t\t\tboard.filter((e) => !!e.cardId).filter((e) => (excludeSource ? e.entityId !== source.entityId : true)),\r\n\t\t\thero,\r\n\t\t\trace,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tif (target) {\r\n\t\t\tmodifyStats(target, source, attack, health, board, hero, gameState);\r\n\t\t\treturn target;\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const getRandomAliveMinion = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\trace: Race,\r\n\tgameState: FullGameState,\r\n): BoardEntity => {\r\n\tconst validTribes = board\r\n\t\t.filter((e) => !race || hasCorrectTribe(e, hero, race, gameState.anomalies, gameState.allCards))\r\n\t\t.filter((e) => e?.health > 0 && !e.definitelyDead);\r\n\tif (!validTribes.length) {\r\n\t\treturn null;\r\n\t}\r\n\tconst randomIndex = Math.floor(Math.random() * validTribes.length);\r\n\treturn validTribes[randomIndex];\r\n};\r\n\r\nexport const getRandomRevivableMinion = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\trace: Race,\r\n\tgameState: FullGameState,\r\n): BoardEntity => {\r\n\tconst validTribes = board\r\n\t\t.filter((e) => !race || hasCorrectTribe(e, hero, race, gameState.anomalies, gameState.allCards))\r\n\t\t.filter((e) => !e.definitelyDead);\r\n\tif (!validTribes.length) {\r\n\t\treturn null;\r\n\t}\r\n\tconst randomIndex = Math.floor(Math.random() * validTribes.length);\r\n\treturn validTribes[randomIndex];\r\n};\r\n\r\nexport const getRandomMinionWithHighestHealth = (board: BoardEntity[]): BoardEntity => {\r\n\tif (!board.length) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst highestHealth = Math.max(...board.map((e) => e.health));\r\n\tconst validMinions = board.filter((e) => e.health === highestHealth);\r\n\treturn validMinions[Math.floor(Math.random() * validMinions.length)];\r\n};\r\n\r\n/** Adds persistent tavern spell bonuses (from minions, trinkets, Bananas, etc.) to base spell-granted stats. */\r\nexport const withTavernSpellStatBuff = (\r\n\thero: BgsPlayerEntity,\r\n\tbaseAttack: number,\r\n\tbaseHealth: number,\r\n\tallCards?: AllCardsService,\r\n\tspellCardId?: string,\r\n): { attack: number; health: number } => {\r\n\tif (allCards && spellCardId) {\r\n\t\tconst school = allCards.getCard(spellCardId)?.spellSchool;\r\n\t\tif (school != null && school !== SpellSchool[SpellSchool.TAVERN]) {\r\n\t\t\treturn { attack: baseAttack, health: baseHealth };\r\n\t\t}\r\n\t}\r\n\treturn {\r\n\t\tattack: baseAttack + (hero.globalInfo.TavernSpellAttackBuff ?? 0),\r\n\t\thealth: baseHealth + (hero.globalInfo.TavernSpellHealthBuff ?? 0),\r\n\t};\r\n};\r\n\r\n/**\r\n * Only use if the full board gets the stats, or if you're able to filter use the tribe param.\r\n * Otherwise some minions will be missing when applying onStatsUpdate effects\r\n */\r\nexport const addStatsToBoard = (\r\n\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\ttribe?: string,\r\n\tcountsAsStatsGain = true,\r\n): void => {\r\n\tconst targetTribe = tribe ? Race[tribe] : null;\r\n\tfor (const entity of board) {\r\n\t\tif (!tribe || hasCorrectTribe(entity, hero, targetTribe, gameState.anomalies, gameState.allCards)) {\r\n\t\t\tif (countsAsStatsGain) {\r\n\t\t\t\tmodifyStats(entity, sourceEntity, attack, health, board, hero, gameState);\r\n\t\t\t} else {\r\n\t\t\t\tentity.attack += attack;\r\n\t\t\t\tentity.health += health;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const addStatsToAliveBoard = (\r\n\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\ttribe?: string,\r\n\t// permanentUpgrade = false,\r\n): void => {\r\n\tconst targetTribe = tribe ? Race[tribe] : null;\r\n\tfor (const entity of board.filter((e) => e.health > 0 && !e.definitelyDead)) {\r\n\t\tif (!tribe || hasCorrectTribe(entity, hero, targetTribe, gameState.anomalies, gameState.allCards)) {\r\n\t\t\tmodifyStats(entity, sourceEntity, attack, health, board, hero, gameState);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const grantStatsToMinionsOfEachType = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\tnumberOfDifferentTypes = 99,\r\n\tcanRevive = true,\r\n): void => {\r\n\tconst minionsToBuff = getMinionsOfDifferentTypes(board, hero, gameState, canRevive, numberOfDifferentTypes);\r\n\tfor (const entity of minionsToBuff) {\r\n\t\tmodifyStats(entity, source, attack, health, board, hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const getMinionsOfDifferentTypes = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tcanRevive = true,\r\n\tnumberOfDifferentTypes = 99,\r\n): BoardEntity[] => {\r\n\tconst result: BoardEntity[] = [];\r\n\tif (board.length > 0) {\r\n\t\tlet boardCopy = board.filter(\r\n\t\t\t(e) => !getEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards)?.includes(Race.ALL),\r\n\t\t);\r\n\t\tconst allRaces = shuffleArray(ALL_BG_RACES);\r\n\t\tlet typesBuffed = 0;\r\n\t\tconst racesProcessed = [];\r\n\t\tfor (let i = 1; i <= 2; i++) {\r\n\t\t\tfor (const tribe of allRaces) {\r\n\t\t\t\tconst minionsWithRaces = boardCopy\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\tgetEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards).length === i,\r\n\t\t\t\t\t)\r\n\t\t\t\t\t.filter((e) => hasCorrectTribe(e, hero, tribe, gameState.anomalies, gameState.allCards))\r\n\t\t\t\t\t.filter((e) =>\r\n\t\t\t\t\t\tgetEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards).some(\r\n\t\t\t\t\t\t\t(r) => !racesProcessed.includes(r),\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t);\r\n\t\t\t\tif (typesBuffed >= numberOfDifferentTypes) {\r\n\t\t\t\t\treturn result;\r\n\t\t\t\t}\r\n\t\t\t\tconst validMinion: BoardEntity = canRevive\r\n\t\t\t\t\t? getRandomRevivableMinion(minionsWithRaces, hero, tribe, gameState)\r\n\t\t\t\t\t: getRandomAliveMinion(minionsWithRaces, hero, tribe, gameState);\r\n\t\t\t\tif (validMinion) {\r\n\t\t\t\t\tresult.push(validMinion);\r\n\t\t\t\t\tboardCopy = boardCopy.filter((e) => e !== validMinion);\r\n\t\t\t\t\ttypesBuffed++;\r\n\t\t\t\t\tracesProcessed.push(tribe);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tresult.push(\r\n\t\t\t...board.filter((e) => {\r\n\t\t\t\tconst effectiveTribes = getEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards);\r\n\t\t\t\treturn effectiveTribes?.includes(Race.ALL);\r\n\t\t\t}),\r\n\t\t);\r\n\t}\r\n\treturn result;\r\n};\r\n\r\nexport const hasMechanic = (card: ReferenceCard, mechanic: GameTag): boolean => {\r\n\treturn card.mechanics?.includes(GameTag[mechanic]);\r\n};\r\n\r\n// The card-level part of hasEntityMechanic is static per cardId, so cache it.\r\n// 1 = yes, 0 = no (both final answers); 2 = the card itself doesn't have the mechanic,\r\n// so we still need to walk the entity's enchantments (only when the card has no entityDbfIf)\r\nconst entityMechanicCache = new Map<GameTag, Map<string, number>>();\r\n\r\nexport const hasEntityMechanic = (\r\n\tentity: BoardEntity | BoardEnchantment,\r\n\tmechanic: GameTag,\r\n\tallCards: AllCardsService,\r\n): boolean => {\r\n\tlet mechanicCache = entityMechanicCache.get(mechanic);\r\n\tif (mechanicCache === undefined) {\r\n\t\tmechanicCache = new Map<string, number>();\r\n\t\tentityMechanicCache.set(mechanic, mechanicCache);\r\n\t}\r\n\tlet cardResult = mechanicCache.get(entity.cardId);\r\n\tif (cardResult === undefined) {\r\n\t\tconst card = allCards.getCard(entity.cardId);\r\n\t\tif (card.mechanics?.includes(GameTag[mechanic])) {\r\n\t\t\tcardResult = 1;\r\n\t\t} else if (card.entityDbfIf) {\r\n\t\t\t// Look at the base card\r\n\t\t\tcardResult = hasMechanic(allCards.getCard(card.entityDbfIf), mechanic) ? 1 : 0;\r\n\t\t} else {\r\n\t\t\tcardResult = 2;\r\n\t\t}\r\n\t\tmechanicCache.set(entity.cardId, cardResult);\r\n\t}\r\n\tif (cardResult === 1) {\r\n\t\treturn true;\r\n\t}\r\n\tif (cardResult === 0) {\r\n\t\treturn false;\r\n\t}\r\n\tconst enchantments = (entity as BoardEntity).enchantments;\r\n\tif (enchantments?.length) {\r\n\t\tfor (const enchant of enchantments) {\r\n\t\t\tif (hasEntityMechanic(enchant, mechanic, allCards)) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nexport const hasCorrectTribe = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\ttargetTribe: Race,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): boolean => {\r\n\t// Safeguard against abusive casts\r\n\tif (entity == null || !entity.maxHealth) {\r\n\t\treturn false;\r\n\t}\r\n\tconst effectiveTribesForEntity = getEffectiveTribesForEntity(entity, playerEntity, anomalies, allCards);\r\n\treturn (\r\n\t\teffectiveTribesForEntity.length > 0 &&\r\n\t\t(effectiveTribesForEntity.includes(targetTribe) || effectiveTribesForEntity.includes(Race.ALL))\r\n\t);\r\n};\r\n\r\nexport const isVolumizer = (\r\n\tcardId: string | number,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): boolean => {\r\n\tif (cardId == null) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst refCard = allCards.getCard(cardId);\r\n\treturn refCard.mechanics?.includes('BACON_VOLUMIZER');\r\n};\r\n\r\n/**\r\n * Useful in cases where a volumizer is summoned from hand, where the volumizer buff is already applied\r\n */\r\nexport const alreadyHasVolumizerBuff = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): boolean => {\r\n\treturn entity.enchantments?.some((e) => e.cardId?.includes('BG34_170'));\r\n};\r\n\r\n// Native tribes never change for a given cardId, so we can compute them once per process\r\n// instead of re-mapping race strings to enums on every call (this is one of the hottest paths\r\n// of the simulation)\r\nconst nativeTribesCache = new Map<string, { tribes: readonly Race[]; isBaconBuddy: boolean }>();\r\nconst NO_TRIBES: readonly Race[] = [];\r\nconst ALL_TRIBES: readonly Race[] = [Race.ALL];\r\n\r\nexport const getEffectiveTribesForEntity = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): readonly Race[] => {\r\n\t// When we trigger a remembered deathrattle, the tribe is the tribe of the actual minion, not the remembered effect\r\n\tconst cardId = entity?.originalCardId ?? entity?.cardId;\r\n\tif (!cardId) {\r\n\t\treturn NO_TRIBES;\r\n\t}\r\n\tlet cached = nativeTribesCache.get(cardId);\r\n\tif (cached === undefined) {\r\n\t\tconst refCard = allCards.getCard(cardId);\r\n\t\tcached = {\r\n\t\t\ttribes: refCard.races?.length ? refCard.races.map((r) => Race[r]) : NO_TRIBES,\r\n\t\t\tisBaconBuddy: refCard.mechanics?.includes(GameTag[GameTag.BACON_BUDDY]) ?? false,\r\n\t\t};\r\n\t\tnativeTribesCache.set(cardId, cached);\r\n\t}\r\n\tconst nativeTribes = cached.tribes;\r\n\tif (anomalies?.length) {\r\n\t\tif (!nativeTribes.length && anomalies.includes(CardIds.IncubationMutation_BG31_Anomaly_112)) {\r\n\t\t\treturn ALL_TRIBES;\r\n\t\t}\r\n\t\tif (cached.isBaconBuddy && anomalies.includes(CardIds.ColorfulCamaraderie_BG33_Anomaly_005)) {\r\n\t\t\treturn ALL_TRIBES;\r\n\t\t}\r\n\t}\r\n\t// The Amalgamation Dark Gift grants all minion types, and is an enchantment rather than a card change\r\n\tif (\r\n\t\tentity.enchantments?.some(\r\n\t\t\t(e) => e.cardId === CardIds.Amalgamation_AmalgamationEnchantment_BG36_MidGameEffect_000t22e,\r\n\t\t)\r\n\t) {\r\n\t\treturn ALL_TRIBES;\r\n\t}\r\n\tconst specialTribes = getSpecialTribesForEntity(entity, playerEntity, allCards);\r\n\tif (!specialTribes.length) {\r\n\t\treturn nativeTribes;\r\n\t}\r\n\treturn [...nativeTribes, ...specialTribes];\r\n};\r\n\r\nconst getSpecialTribesForEntity = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n): readonly Race[] => {\r\n\tswitch (entity.cardId) {\r\n\t\tcase CardIds.WhelpSmuggler_BG21_013:\r\n\t\tcase CardIds.WhelpSmuggler_BG21_013_G:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.SmugglerPortrait_BG30_MagicItem_825)\r\n\t\t\t\t? [Race.DRAGON]\r\n\t\t\t\t: NO_TRIBES;\r\n\t\tcase CardIds.LightfangEnforcer_BGS_009:\r\n\t\tcase CardIds.LightfangEnforcer_TB_BaconUps_082:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.EnforcerPortrait_BG30_MagicItem_971)\r\n\t\t\t\t? ALL_TRIBES\r\n\t\t\t\t: NO_TRIBES;\r\n\t\tcase CardIds.BrannBronzebeard_BG_LOE_077:\r\n\t\tcase CardIds.BrannBronzebeard_TB_BaconUps_045:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.BronzebeardPortrait_BG30_MagicItem_418)\r\n\t\t\t\t? [Race.DRAGON, Race.MURLOC]\r\n\t\t\t\t: NO_TRIBES;\r\n\t\tcase CardIds.DrakkariEnchanter_BG26_ICC_901:\r\n\t\tcase CardIds.DrakkariEnchanter_BG26_ICC_901_G:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.DrakkariPortrait_BG32_MagicItem_179)\r\n\t\t\t\t? [Race.MECH, Race.ELEMENTAL]\r\n\t\t\t\t: NO_TRIBES;\r\n\t}\r\n\treturn NO_TRIBES;\r\n};\r\n\r\n/** @deprecated use hasCorreectTribe instead */\r\nexport const isCorrectTribe = (cardRaces: readonly string[], targetTribe: Race): boolean => {\r\n\tif (!cardRaces?.length) {\r\n\t\treturn false;\r\n\t}\r\n\treturn cardRaces\r\n\t\t.map((cardRace) => getRaceEnum(cardRace))\r\n\t\t.some((raceEnum) => raceEnum === Race.ALL || raceEnum === targetTribe);\r\n};\r\n\r\nexport const getRaceEnum = (race: string): Race => {\r\n\treturn Race[race];\r\n};\r\n\r\nconst IMMUNE_WHEN_ATTACK_IDS = new Set<string>([\r\n\tCardIds.Warpwing_BG24_004,\r\n\tCardIds.Warpwing_BG24_004_G,\r\n\tCardIds.KerriganQueenOfBlades_ViperToken_BG31_HERO_811t8,\r\n\tCardIds.Viper_BG31_HERO_811t8_G,\r\n\tCardIds.TimewarpedViper_BG34_Treasure_990,\r\n\tCardIds.TimewarpedViper_BG34_Treasure_990_G,\r\n]);\r\nconst THREE_CHARGES_IDS = new Set<string>([\r\n\t// CardIds.MarineMatriarch_BG29_610,\r\n\t// CardIds.MarineMatriarch_BG29_610_G,\r\n\t// CardIds.SoftHeartedSiren_BG26_590,\r\n\t// CardIds.SoftHeartedSiren_BG26_590_G,\r\n\t// CardIds.LongJohnCopper_BG29_831,\r\n\t// CardIds.LongJohnCopper_BG29_831_G,\r\n\t// CardIds.BristlingBuffoon_BG29_160,\r\n\t// CardIds.BristlingBuffoon_BG29_160_G,\r\n]);\r\nconst TWO_CHARGES_IDS = new Set<string>([\r\n\tCardIds.Mannoroth_BG27_507_G,\r\n\tCardIds.EclipsionIllidari_TB_BaconShop_HERO_08_Buddy_G,\r\n\tCardIds.MadMatador_BG28_404_G,\r\n\tCardIds.WingedChimera_BG29_844,\r\n\tCardIds.WingedChimera_BG29_844_G,\r\n\tCardIds.MossOfTheSchloss_BG30_111_G,\r\n]);\r\n\r\nexport const addImpliedMechanics = (entity: BoardEntity, cardsData: CardsData): BoardEntity => {\r\n\tentity.cleave = CLEAVE_IDS.has(entity.cardId);\r\n\tentity.cantAttack = CANT_ATTACK_IDS.has(entity.cardId);\r\n\tentity.divineShield = entity.divineShield || entity.hadDivineShield;\r\n\tif (\r\n\t\tentity.enchantments?.some(\r\n\t\t\t(e) => e.cardId === CardIds.TorethsBlessing_TorethsBlessingEnchantment_BG36_MidGameEffect_000t15e,\r\n\t\t)\r\n\t) {\r\n\t\tentity.divineShield = true;\r\n\t\tentity.extraDivineShieldCharges = (entity.extraDivineShieldCharges ?? 0) + extraHits;\r\n\t}\r\n\tentity.immuneWhenAttackCharges = IMMUNE_WHEN_ATTACK_IDS.has(entity.cardId) ? 99999 : null;\r\n\tentity.frenzyChargesLeft =\r\n\t\tentity.cardId === CardIds.BristlebackKnight_BG20_204_G\r\n\t\t\t? 2\r\n\t\t\t: entity.cardId === CardIds.BristlebackKnight_BG20_204\r\n\t\t\t? 1\r\n\t\t\t: 0;\r\n\t// It's not an issue adding a charge for entities without a special ability\r\n\tconst defaultChargesImpl = cardMappings[entity.cardId];\r\n\tif (hasDefaultCharges(defaultChargesImpl)) {\r\n\t\tentity.abiityChargesLeft = defaultChargesImpl.defaultCharges(entity);\r\n\t} else {\r\n\t\tentity.abiityChargesLeft = THREE_CHARGES_IDS.has(entity.cardId) ? 3 : TWO_CHARGES_IDS.has(entity.cardId) ? 2 : 1;\r\n\t}\r\n\r\n\treturn setImplicitDataForEntity(entity, cardsData);\r\n};\r\n\r\nconst setImplicitDataForEntity = (entity: BoardEntity, cardsData: CardsData): BoardEntity => {\r\n\tentity.cardId = normalizeCardIdForSkin(entity.cardId);\r\n\tentity.maxHealth = Math.max(0, entity.health, entity.maxHealth ?? 0);\r\n\tentity.maxAttack = Math.max(0, entity.attack, entity.maxAttack ?? 0);\r\n\tconst avengeValue = cardsData.avengeValue(entity.cardId);\r\n\tif (avengeValue > 0) {\r\n\t\tentity.avengeCurrent = avengeValue;\r\n\t\tentity.avengeDefault = avengeValue;\r\n\t}\r\n\treturn entity;\r\n};\r\n\r\nexport const normalizeCardIdForSkin = (cardId: string): string => {\r\n\tif (!cardId?.length) {\r\n\t\treturn cardId;\r\n\t}\r\n\t// Quick check to avoid the regex allocation in the (very common) non-skin case\r\n\t// lastIndexOf to mirror the greedy behavior of the previous /(.*)_SKIN_.*/ regex\r\n\tconst skinIndex = cardId.lastIndexOf('_SKIN_');\r\n\tif (skinIndex === -1) {\r\n\t\treturn cardId;\r\n\t}\r\n\treturn cardId.slice(0, skinIndex);\r\n};\r\n\r\nexport const stringifySimple = (board: readonly BoardEntity[], allCards: AllCardsService = null): string => {\r\n\treturn '[' + board.map((entity) => stringifySimpleCard(entity, allCards)).join(', ') + ']';\r\n};\r\n\r\nexport const stringifySimpleCard = (entity: BoardEntity, allCards: AllCardsService = null): string => {\r\n\treturn entity\r\n\t\t? `${allCards?.getCard(entity.cardId)?.name ?? entity.cardId}/entityId=${entity.entityId}/atk=${\r\n\t\t\t\tentity.attack\r\n\t\t }/hp=${entity.health}/ench=${entity.enchantments.map((e) => e.cardId).join(',')}`\r\n\t\t: null;\r\n};\r\n\r\nexport const isFish = (entity: BoardEntity): boolean => {\r\n\treturn (\r\n\t\tentity.cardId?.startsWith(CardIds.AvatarOfNzoth_FishOfNzothToken) ||\r\n\t\tentity.cardId?.startsWith(CardIds.FishOfNzoth)\r\n\t);\r\n};\r\n\r\nexport const isPilotedWhirlOTron = (entity: BoardEntity): boolean => {\r\n\treturn entity.cardId?.startsWith(CardIds.PilotedWhirlOTron_BG21_HERO_030_Buddy);\r\n};\r\n\r\nexport const isGolden = (cardId: string, allCards: AllCardsService): boolean => {\r\n\treturn allCards.getCard(cardId).premium;\r\n};\r\n\r\nexport const isBoardEntity = (entity: BoardEntity | BoardTrinket): entity is BoardEntity => {\r\n\treturn entity != null && 'maxHealth' in entity;\r\n};\r\n\r\nexport const getPlayerState = (gameState: GameState, hero: BgsPlayerEntity): PlayerState => {\r\n\treturn gameState.player.player === hero\r\n\t\t? gameState.player\r\n\t\t: gameState.player.teammate?.player === hero\r\n\t\t? gameState.player.teammate\r\n\t\t: gameState.opponent.player === hero\r\n\t\t? gameState.opponent\r\n\t\t: gameState.opponent.teammate?.player === hero\r\n\t\t? gameState.opponent.teammate\r\n\t\t: null;\r\n};\r\n\r\nexport const getTeammateInitialState = (gameState: GameState, hero: BgsPlayerEntity): PlayerState => {\r\n\treturn gameState.playerInitial.player?.entityId === hero?.entityId\r\n\t\t? gameState.playerInitial.teammate\r\n\t\t: gameState.playerInitial.teammate?.player?.entityId === hero?.entityId\r\n\t\t? gameState.playerInitial\r\n\t\t: gameState.opponentInitial.player?.entityId === hero?.entityId\r\n\t\t? gameState.opponentInitial.teammate\r\n\t\t: gameState.opponentInitial.teammate?.player?.entityId === hero?.entityId\r\n\t\t? gameState.opponentInitial\r\n\t\t: null;\r\n};\r\n\r\nexport const getTeamInitialStates = (gameState: GameState, hero: BgsPlayerEntity): PlayerState[] => {\r\n\treturn gameState.playerInitial.player?.friendly === hero?.friendly\r\n\t\t? [gameState.playerInitial, gameState.playerInitial.teammate].filter((p) => p)\r\n\t\t: [gameState.opponentInitial, gameState.opponentInitial.teammate].filter((p) => p);\r\n};\r\n\r\nexport const getPlayerInitialState = (gameState: GameState, hero: BgsPlayerEntity): PlayerState => {\r\n\treturn gameState.playerInitial.player?.friendly === hero?.friendly\r\n\t\t? gameState.playerInitial\r\n\t\t: gameState.opponentInitial;\r\n};\r\n\r\nexport const copyEntity = (entity: BoardEntity): BoardEntity => {\r\n\tconst copy: BoardEntity = {\r\n\t\t...entity,\r\n\t\tenchantments: (entity.enchantments ?? []).map((ench) => ({ ...ench })),\r\n\t\tpendingAttackBuffs: [],\r\n\t\trememberedDeathrattles: (entity.rememberedDeathrattles ?? []).map((r) => ({ ...r })),\r\n\t\tadditionalCards: entity.additionalCards?.map((c) => c),\r\n\t\ttags: entity.tags ? { ...entity.tags } : null,\r\n\t\tlastAffectedByEntity: null,\r\n\t};\r\n\treturn copy;\r\n};\r\n\r\nexport const isDead = (entity: BoardEntity): boolean => {\r\n\treturn entity.health <= 0 || entity.definitelyDead;\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { ALL_BG_RACES, AllCardsService, GameTag, Race, ReferenceCard, SpellSchool } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity, BoardTrinket } from './bgs-player-entity';\r\nimport { BoardEnchantment, BoardEntity } from './board-entity';\r\nimport { BoardSecret } from './board-secret';\r\nimport { hasDefaultCharges } from './cards/card.interface';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { cardMappings } from './cards/impl/_card-mappings';\r\nimport { extraHits } from './cards/impl/enchantments/toreths-blessing';\r\nimport { CardIds } from './services/card-ids';\r\nimport { pickRandom, shuffleArray } from './services/utils';\r\nimport { FullGameState, GameState, PlayerState } from './simulation/internal-game-state';\r\nimport { SharedState } from './simulation/shared-state';\r\nimport { modifyStats } from './simulation/stats';\r\n\r\nconst CLEAVE_IDS = new Set<string>([\r\n\tCardIds.CaveHydra_BG_LOOT_078,\r\n\tCardIds.CaveHydra_TB_BaconUps_151,\r\n\tCardIds.FoeReaper4000_BG_GVG_113,\r\n\tCardIds.FoeReaper4000_TB_BaconUps_153,\r\n\tCardIds.BladeCollector_BG26_817,\r\n\tCardIds.BladeCollector_BG26_817_G,\r\n\tCardIds.KerriganQueenOfBlades_UltraliskToken_BG31_HERO_811t10,\r\n\tCardIds.Ultralisk_BG31_HERO_811t10_G,\r\n\tCardIds.TimewarpedUltralisk_BG34_Treasure_994,\r\n\tCardIds.TimewarpedUltralisk_BG34_Treasure_994_G,\r\n\tCardIds.TimewarpedCollector_BG34_Giant_680,\r\n\tCardIds.TimewarpedCollector_BG34_Giant_680_G,\r\n]);\r\nconst ATTACK_IMMEDIATELY_IDS = [\r\n\tCardIds.Scallywag_SkyPirateToken_BGS_061t,\r\n\tCardIds.Scallywag_SkyPirateToken_TB_BaconUps_141t,\r\n\tCardIds.Onyxia_OnyxianWhelpToken,\r\n\tCardIds.TwilightWhelp_WhelpToken,\r\n\tCardIds.TwilightHatchling_TwilightWhelpToken_BG34_630t,\r\n\tCardIds.TwilightHatchling_TwilightWhelpToken_BG34_630_Gt,\r\n\t// CardIds.Carrier_InterceptorToken_BG31_HERO_802pt1t,\r\n\t// CardIds.Interceptor_BG31_HERO_802pt1t_G,\r\n\t// The token doesn't attack immediately natively, only when spawned by the spell\r\n\t// See http://replays.firestoneapp.com/?reviewId=8924452a-540a-4324-8306-46900c3f9f35&turn=22&action=38\r\n\t// CardIds.ToxicTumbleweed_TumblingAssassinToken_BG28_641t,\r\n];\r\nconst CANT_ATTACK_IDS = new Set<string>([\r\n\t// CardIds.ArcaneCannon_BGS_077, CardIds.ArcaneCannon_TB_BaconUps_128\r\n]);\r\n\r\nexport const buildSingleBoardEntity = (\r\n\tcardId: string,\r\n\tcontrollerHero: BgsPlayerEntity,\r\n\tfriendlyBoard: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tfriendly: boolean,\r\n\tentityId = 1,\r\n\tspawnReborn = false,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tentityToSpawn: BoardEntity,\r\n\toriginalEntity: BoardEntity = null,\r\n\toptions: {\r\n\t\treferenceCardToUse: ReferenceCard;\r\n\t} = null,\r\n): BoardEntity => {\r\n\tconst trueRefCard = allCards.getCard(cardId);\r\n\tconst card = options?.referenceCardToUse ?? trueRefCard;\r\n\tconst attackImmediately = ATTACK_IMMEDIATELY_IDS.indexOf(cardId as CardIds) !== -1;\r\n\tconst newEntity = !!entityToSpawn\r\n\t\t? ({\r\n\t\t\t\t...entityToSpawn,\r\n\t\t\t\tentityId: sharedState.currentEntityId++,\r\n\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\tavengeCurrent: entityToSpawn.avengeDefault,\r\n\t\t\t\t// attacking: false,\r\n\t\t\t\tdamageMultiplier: 1,\r\n\t\t\t\tfrenzyChargesLeft: 1,\r\n\t\t\t\tfriendly: friendly,\r\n\t\t\t\thasAttacked: undefined,\r\n\t\t } as BoardEntity)\r\n\t\t: addImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\tentityId: entityId,\r\n\t\t\t\t\tattack: card.attack,\r\n\t\t\t\t\thasAttacked: undefined,\r\n\t\t\t\t\tcardId: cardId,\r\n\t\t\t\t\tdivineShield: hasMechanic(card, GameTag.DIVINE_SHIELD),\r\n\t\t\t\t\thealth: card.health,\r\n\t\t\t\t\tmaxHealth: card.health || trueRefCard.health,\r\n\t\t\t\t\tmaxAttack: card.attack || trueRefCard.attack,\r\n\t\t\t\t\ttaunt: hasMechanic(card, GameTag.TAUNT),\r\n\t\t\t\t\treborn: hasMechanic(card, GameTag.REBORN),\r\n\t\t\t\t\tpoisonous: hasMechanic(card, GameTag.POISONOUS),\r\n\t\t\t\t\tvenomous: hasMechanic(card, GameTag.VENOMOUS),\r\n\t\t\t\t\tstealth: hasMechanic(card, GameTag.STEALTH),\r\n\t\t\t\t\twindfury: hasMechanic(card, GameTag.WINDFURY),\r\n\t\t\t\t\tenchantments: [],\r\n\t\t\t\t\tpendingAttackBuffs: [],\r\n\t\t\t\t\tfriendly: friendly,\r\n\t\t\t\t\tattackImmediately: attackImmediately,\r\n\t\t\t\t\tavengeCurrent: cardsData.avengeValue(cardId),\r\n\t\t\t\t\tavengeDefault: cardsData.avengeValue(cardId),\r\n\t\t\t\t\tscriptDataNum1: originalEntity?.scriptDataNum1 ?? 0,\r\n\t\t\t\t\t// This is useful for Showy Cycilst, but I wonder if this could cause some issues otherwise\r\n\t\t\t\t\tscriptDataNum2: originalEntity?.scriptDataNum2 ?? 0,\r\n\t\t\t\t} as BoardEntity,\r\n\t\t\t\tcardsData,\r\n\t\t );\r\n\r\n\tif (spawnReborn && !entityToSpawn) {\r\n\t\tif (cardId === CardIds.BuildAnUndead_PutricidesCreationToken) {\r\n\t\t\tconst stitchedCardId = !!originalEntity.additionalCards?.length ? originalEntity.additionalCards[0] : null;\r\n\t\t\tif (stitchedCardId) {\r\n\t\t\t\tconst stitchedCard = allCards.getCard(stitchedCardId);\r\n\t\t\t\tnewEntity.attack = newEntity.attack + stitchedCard.attack;\r\n\t\t\t\tnewEntity.maxHealth = newEntity.maxHealth + stitchedCard.health;\r\n\t\t\t\tnewEntity.taunt = newEntity.taunt || hasMechanic(stitchedCard, GameTag.TAUNT);\r\n\t\t\t\tnewEntity.divineShield = newEntity.divineShield || hasMechanic(stitchedCard, GameTag.DIVINE_SHIELD);\r\n\t\t\t\tnewEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;\r\n\t\t\t\tnewEntity.poisonous = newEntity.poisonous || hasMechanic(stitchedCard, GameTag.POISONOUS);\r\n\t\t\t\tnewEntity.venomous = newEntity.venomous || hasMechanic(stitchedCard, GameTag.VENOMOUS);\r\n\t\t\t\tnewEntity.windfury = newEntity.windfury || hasMechanic(stitchedCard, GameTag.WINDFURY);\r\n\t\t\t\tnewEntity.avengeCurrent = newEntity.avengeCurrent || cardsData.avengeValue(stitchedCardId);\r\n\t\t\t\tnewEntity.avengeDefault = newEntity.avengeDefault || cardsData.avengeValue(stitchedCardId);\r\n\t\t\t}\r\n\t\t} else if (\r\n\t\t\tcardId === CardIds.ZilliaxAssembled_BG29_100_G &&\r\n\t\t\t!!originalEntity.additionalCards?.filter((c) => !!c).length\r\n\t\t) {\r\n\t\t\t// In this case, the base stats are still correct (the golden stats of Zilliax), but the keywords\r\n\t\t\t// can change\r\n\t\t\tfor (const moduleCardId of originalEntity.additionalCards) {\r\n\t\t\t\tconst moduleCard = allCards.getCard(moduleCardId);\r\n\t\t\t\tnewEntity.taunt = newEntity.taunt || hasMechanic(moduleCard, GameTag.TAUNT);\r\n\t\t\t\tnewEntity.divineShield = newEntity.divineShield || hasMechanic(moduleCard, GameTag.DIVINE_SHIELD);\r\n\t\t\t\tnewEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;\r\n\t\t\t\tnewEntity.poisonous = newEntity.poisonous || hasMechanic(moduleCard, GameTag.POISONOUS);\r\n\t\t\t\tnewEntity.venomous = newEntity.venomous || hasMechanic(moduleCard, GameTag.VENOMOUS);\r\n\t\t\t\tnewEntity.windfury = newEntity.windfury || hasMechanic(moduleCard, GameTag.WINDFURY);\r\n\t\t\t\tnewEntity.stealth = newEntity.stealth || hasMechanic(moduleCard, GameTag.STEALTH);\r\n\t\t\t}\r\n\t\t}\r\n\t\tnewEntity.health = 1;\r\n\t\tnewEntity.reborn = false;\r\n\t\tnewEntity.scriptDataNum1 = getScriptDataNum1(cardId, originalEntity);\r\n\r\n\t\t// For ghoul-acabra + reborn\r\n\t\t// newEntity.attack += originalEntity.permanentAttack ?? 0;\r\n\t\t// newEntity.health += originalEntity.permanentHealth ?? 0;\r\n\t}\r\n\r\n\tnewEntity.hadDivineShield = newEntity.divineShield || newEntity.hadDivineShield;\r\n\treturn newEntity;\r\n};\r\n\r\nconst getScriptDataNum1 = (cardId: string, originalEntity: BoardEntity): number => {\r\n\tswitch (cardId) {\r\n\t\tcase CardIds.OctosariWrapGod_BG26_804:\r\n\t\t\treturn 8;\r\n\t\tcase CardIds.OctosariWrapGod_BG26_804_G:\r\n\t\t\treturn 16;\r\n\t\tdefault:\r\n\t\t\treturn 0;\r\n\t}\r\n};\r\n\r\nexport const buildRandomUndeadCreation = (\r\n\tcontrollerHero: BgsPlayerEntity,\r\n\tfriendlyBoard: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tfriendly: boolean,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n): BoardEntity => {\r\n\tconst baseCard = pickRandom(cardsData.putricidePool1);\r\n\tconst newEntity = buildSingleBoardEntity(\r\n\t\tbaseCard,\r\n\t\tcontrollerHero,\r\n\t\tfriendlyBoard,\r\n\t\tallCards,\r\n\t\tfriendly,\r\n\t\tsharedState.currentEntityId++,\r\n\t\tfalse,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tnull,\r\n\t);\r\n\r\n\tconst stitchedCardId =\r\n\t\tbaseCard === CardIds.EternalSummoner_BG25_009\r\n\t\t\t? pickRandom(cardsData.putridicePool2ForEternalSummoner)\r\n\t\t\t: pickRandom(cardsData.putricidePool2);\r\n\tconst stitchedCard = allCards.getCard(stitchedCardId);\r\n\tnewEntity.attack += stitchedCard.attack;\r\n\tnewEntity.health += stitchedCard.health;\r\n\tnewEntity.maxHealth = (newEntity.maxHealth ?? newEntity.health) + stitchedCard.health;\r\n\tnewEntity.maxAttack = (newEntity.maxAttack ?? newEntity.attack - stitchedCard.attack) + stitchedCard.attack;\r\n\tnewEntity.taunt = newEntity.taunt || hasMechanic(stitchedCard, GameTag.TAUNT);\r\n\tnewEntity.divineShield = newEntity.divineShield || hasMechanic(stitchedCard, GameTag.DIVINE_SHIELD);\r\n\tnewEntity.hadDivineShield = newEntity.hadDivineShield || newEntity.divineShield;\r\n\tnewEntity.poisonous = newEntity.poisonous || hasMechanic(stitchedCard, GameTag.POISONOUS);\r\n\tnewEntity.venomous = newEntity.venomous || hasMechanic(stitchedCard, GameTag.VENOMOUS);\r\n\tnewEntity.windfury = newEntity.windfury || hasMechanic(stitchedCard, GameTag.WINDFURY);\r\n\tnewEntity.reborn = newEntity.reborn || hasMechanic(stitchedCard, GameTag.REBORN);\r\n\tnewEntity.avengeCurrent = newEntity.avengeCurrent || cardsData.avengeValue(stitchedCardId);\r\n\tnewEntity.avengeDefault = newEntity.avengeDefault || cardsData.avengeValue(stitchedCardId);\r\n\tnewEntity.additionalCards = [stitchedCardId];\r\n\treturn newEntity;\r\n};\r\n\r\nexport const grantRandomAttack = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tadditionalAttack: number,\r\n\tgameState: FullGameState,\r\n\texcludeSource = false,\r\n): void => {\r\n\tconst candidateBoard = board\r\n\t\t.filter((e) => !excludeSource || e.entityId !== source.entityId)\r\n\t\t.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tif (candidateBoard.length > 0) {\r\n\t\tconst target = candidateBoard[Math.floor(Math.random() * candidateBoard.length)];\r\n\t\tmodifyStats(target, source, additionalAttack, 0, candidateBoard, hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const grantRandomHealth = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\texcludeSource = false,\r\n): void => {\r\n\tconst candidateBoard = board\r\n\t\t.filter((e) => !excludeSource || e.entityId !== source.entityId)\r\n\t\t.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tif (candidateBoard.length > 0) {\r\n\t\tconst target = pickRandom(candidateBoard);\r\n\t\tmodifyStats(target, source, 0, health, board, hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const grantRandomStats = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\trace: Race,\r\n\texcludeSource: boolean,\r\n\tgameState: FullGameState,\r\n): BoardEntity => {\r\n\tif (board.length > 0) {\r\n\t\tconst target: BoardEntity = getRandomAliveMinion(\r\n\t\t\tboard.filter((e) => !!e.cardId).filter((e) => (excludeSource ? e.entityId !== source.entityId : true)),\r\n\t\t\thero,\r\n\t\t\trace,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tif (target) {\r\n\t\t\tmodifyStats(target, source, attack, health, board, hero, gameState);\r\n\t\t\treturn target;\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const getRandomAliveMinion = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\trace: Race,\r\n\tgameState: FullGameState,\r\n): BoardEntity => {\r\n\tconst validTribes = board\r\n\t\t.filter((e) => !race || hasCorrectTribe(e, hero, race, gameState.anomalies, gameState.allCards))\r\n\t\t.filter((e) => e?.health > 0 && !e.definitelyDead);\r\n\tif (!validTribes.length) {\r\n\t\treturn null;\r\n\t}\r\n\tconst randomIndex = Math.floor(Math.random() * validTribes.length);\r\n\treturn validTribes[randomIndex];\r\n};\r\n\r\nexport const getRandomRevivableMinion = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\trace: Race,\r\n\tgameState: FullGameState,\r\n): BoardEntity => {\r\n\tconst validTribes = board\r\n\t\t.filter((e) => !race || hasCorrectTribe(e, hero, race, gameState.anomalies, gameState.allCards))\r\n\t\t.filter((e) => !e.definitelyDead);\r\n\tif (!validTribes.length) {\r\n\t\treturn null;\r\n\t}\r\n\tconst randomIndex = Math.floor(Math.random() * validTribes.length);\r\n\treturn validTribes[randomIndex];\r\n};\r\n\r\nexport const getRandomMinionWithHighestHealth = (board: BoardEntity[]): BoardEntity => {\r\n\tif (!board.length) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst highestHealth = Math.max(...board.map((e) => e.health));\r\n\tconst validMinions = board.filter((e) => e.health === highestHealth);\r\n\treturn validMinions[Math.floor(Math.random() * validMinions.length)];\r\n};\r\n\r\n/** Adds persistent tavern spell bonuses (from minions, trinkets, Bananas, etc.) to base spell-granted stats. */\r\nexport const withTavernSpellStatBuff = (\r\n\thero: BgsPlayerEntity,\r\n\tbaseAttack: number,\r\n\tbaseHealth: number,\r\n\tallCards?: AllCardsService,\r\n\tspellCardId?: string,\r\n): { attack: number; health: number } => {\r\n\tif (allCards && spellCardId) {\r\n\t\tconst school = allCards.getCard(spellCardId)?.spellSchool;\r\n\t\tif (school != null && school !== SpellSchool[SpellSchool.TAVERN]) {\r\n\t\t\treturn { attack: baseAttack, health: baseHealth };\r\n\t\t}\r\n\t}\r\n\treturn {\r\n\t\tattack: baseAttack + (hero.globalInfo.TavernSpellAttackBuff ?? 0),\r\n\t\thealth: baseHealth + (hero.globalInfo.TavernSpellHealthBuff ?? 0),\r\n\t};\r\n};\r\n\r\n/**\r\n * Only use if the full board gets the stats, or if you're able to filter use the tribe param.\r\n * Otherwise some minions will be missing when applying onStatsUpdate effects\r\n */\r\nexport const addStatsToBoard = (\r\n\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\ttribe?: string,\r\n\tcountsAsStatsGain = true,\r\n): void => {\r\n\tconst targetTribe = tribe ? Race[tribe] : null;\r\n\tfor (const entity of board) {\r\n\t\tif (!tribe || hasCorrectTribe(entity, hero, targetTribe, gameState.anomalies, gameState.allCards)) {\r\n\t\t\tif (countsAsStatsGain) {\r\n\t\t\t\tmodifyStats(entity, sourceEntity, attack, health, board, hero, gameState);\r\n\t\t\t} else {\r\n\t\t\t\tentity.attack += attack;\r\n\t\t\t\tentity.health += health;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const addStatsToAliveBoard = (\r\n\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\ttribe?: string,\r\n\t// permanentUpgrade = false,\r\n): void => {\r\n\tconst targetTribe = tribe ? Race[tribe] : null;\r\n\tfor (const entity of board.filter((e) => e.health > 0 && !e.definitelyDead)) {\r\n\t\tif (!tribe || hasCorrectTribe(entity, hero, targetTribe, gameState.anomalies, gameState.allCards)) {\r\n\t\t\tmodifyStats(entity, sourceEntity, attack, health, board, hero, gameState);\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const grantStatsToMinionsOfEachType = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n\tnumberOfDifferentTypes = 99,\r\n\tcanRevive = true,\r\n): void => {\r\n\tconst minionsToBuff = getMinionsOfDifferentTypes(board, hero, gameState, canRevive, numberOfDifferentTypes);\r\n\tfor (const entity of minionsToBuff) {\r\n\t\tmodifyStats(entity, source, attack, health, board, hero, gameState);\r\n\t}\r\n};\r\n\r\nexport const getMinionsOfDifferentTypes = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tcanRevive = true,\r\n\tnumberOfDifferentTypes = 99,\r\n): BoardEntity[] => {\r\n\tconst result: BoardEntity[] = [];\r\n\tif (board.length > 0) {\r\n\t\tlet boardCopy = board.filter(\r\n\t\t\t(e) => !getEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards)?.includes(Race.ALL),\r\n\t\t);\r\n\t\tconst allRaces = shuffleArray(ALL_BG_RACES);\r\n\t\tlet typesBuffed = 0;\r\n\t\tconst racesProcessed = [];\r\n\t\tfor (let i = 1; i <= 2; i++) {\r\n\t\t\tfor (const tribe of allRaces) {\r\n\t\t\t\tconst minionsWithRaces = boardCopy\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\tgetEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards).length === i,\r\n\t\t\t\t\t)\r\n\t\t\t\t\t.filter((e) => hasCorrectTribe(e, hero, tribe, gameState.anomalies, gameState.allCards))\r\n\t\t\t\t\t.filter((e) =>\r\n\t\t\t\t\t\tgetEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards).some(\r\n\t\t\t\t\t\t\t(r) => !racesProcessed.includes(r),\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t);\r\n\t\t\t\tif (typesBuffed >= numberOfDifferentTypes) {\r\n\t\t\t\t\treturn result;\r\n\t\t\t\t}\r\n\t\t\t\tconst validMinion: BoardEntity = canRevive\r\n\t\t\t\t\t? getRandomRevivableMinion(minionsWithRaces, hero, tribe, gameState)\r\n\t\t\t\t\t: getRandomAliveMinion(minionsWithRaces, hero, tribe, gameState);\r\n\t\t\t\tif (validMinion) {\r\n\t\t\t\t\tresult.push(validMinion);\r\n\t\t\t\t\tboardCopy = boardCopy.filter((e) => e !== validMinion);\r\n\t\t\t\t\ttypesBuffed++;\r\n\t\t\t\t\tracesProcessed.push(tribe);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tresult.push(\r\n\t\t\t...board.filter((e) => {\r\n\t\t\t\tconst effectiveTribes = getEffectiveTribesForEntity(e, hero, gameState.anomalies, gameState.allCards);\r\n\t\t\t\treturn effectiveTribes?.includes(Race.ALL);\r\n\t\t\t}),\r\n\t\t);\r\n\t}\r\n\treturn result;\r\n};\r\n\r\nexport const hasMechanic = (card: ReferenceCard, mechanic: GameTag): boolean => {\r\n\treturn card.mechanics?.includes(GameTag[mechanic]);\r\n};\r\n\r\n// The card-level part of hasEntityMechanic is static per cardId, so cache it.\r\n// 1 = yes, 0 = no (both final answers); 2 = the card itself doesn't have the mechanic,\r\n// so we still need to walk the entity's enchantments (only when the card has no entityDbfIf)\r\nconst entityMechanicCache = new Map<GameTag, Map<string, number>>();\r\n\r\nexport const hasEntityMechanic = (\r\n\tentity: BoardEntity | BoardEnchantment,\r\n\tmechanic: GameTag,\r\n\tallCards: AllCardsService,\r\n): boolean => {\r\n\tlet mechanicCache = entityMechanicCache.get(mechanic);\r\n\tif (mechanicCache === undefined) {\r\n\t\tmechanicCache = new Map<string, number>();\r\n\t\tentityMechanicCache.set(mechanic, mechanicCache);\r\n\t}\r\n\tlet cardResult = mechanicCache.get(entity.cardId);\r\n\tif (cardResult === undefined) {\r\n\t\tconst card = allCards.getCard(entity.cardId);\r\n\t\tif (card.mechanics?.includes(GameTag[mechanic])) {\r\n\t\t\tcardResult = 1;\r\n\t\t} else if (card.entityDbfIf) {\r\n\t\t\t// Look at the base card\r\n\t\t\tcardResult = hasMechanic(allCards.getCard(card.entityDbfIf), mechanic) ? 1 : 0;\r\n\t\t} else {\r\n\t\t\tcardResult = 2;\r\n\t\t}\r\n\t\tmechanicCache.set(entity.cardId, cardResult);\r\n\t}\r\n\tif (cardResult === 1) {\r\n\t\treturn true;\r\n\t}\r\n\tif (cardResult === 0) {\r\n\t\treturn false;\r\n\t}\r\n\tconst enchantments = (entity as BoardEntity).enchantments;\r\n\tif (enchantments?.length) {\r\n\t\tfor (const enchant of enchantments) {\r\n\t\t\tif (hasEntityMechanic(enchant, mechanic, allCards)) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nexport const hasCorrectTribe = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\ttargetTribe: Race,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): boolean => {\r\n\t// Safeguard against abusive casts\r\n\tif (entity == null || !entity.maxHealth) {\r\n\t\treturn false;\r\n\t}\r\n\tconst effectiveTribesForEntity = getEffectiveTribesForEntity(entity, playerEntity, anomalies, allCards);\r\n\treturn (\r\n\t\teffectiveTribesForEntity.length > 0 &&\r\n\t\t(effectiveTribesForEntity.includes(targetTribe) || effectiveTribesForEntity.includes(Race.ALL))\r\n\t);\r\n};\r\n\r\nexport const isVolumizer = (\r\n\tcardId: string | number,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): boolean => {\r\n\tif (cardId == null) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tconst refCard = allCards.getCard(cardId);\r\n\treturn refCard.mechanics?.includes('BACON_VOLUMIZER');\r\n};\r\n\r\n/**\r\n * Useful in cases where a volumizer is summoned from hand, where the volumizer buff is already applied\r\n */\r\nexport const alreadyHasVolumizerBuff = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): boolean => {\r\n\treturn entity.enchantments?.some((e) => e.cardId?.includes('BG34_170'));\r\n};\r\n\r\n// Native tribes never change for a given cardId, so we can compute them once per process\r\n// instead of re-mapping race strings to enums on every call (this is one of the hottest paths\r\n// of the simulation)\r\nconst nativeTribesCache = new Map<string, { tribes: readonly Race[]; isBaconBuddy: boolean }>();\r\nconst NO_TRIBES: readonly Race[] = [];\r\nconst ALL_TRIBES: readonly Race[] = [Race.ALL];\r\n\r\nexport const getEffectiveTribesForEntity = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tanomalies: readonly string[],\r\n\tallCards: AllCardsService,\r\n): readonly Race[] => {\r\n\t// When we trigger a remembered deathrattle, the tribe is the tribe of the actual minion, not the remembered effect\r\n\tconst cardId = entity?.originalCardId ?? entity?.cardId;\r\n\tif (!cardId) {\r\n\t\treturn NO_TRIBES;\r\n\t}\r\n\tlet cached = nativeTribesCache.get(cardId);\r\n\tif (cached === undefined) {\r\n\t\tconst refCard = allCards.getCard(cardId);\r\n\t\tcached = {\r\n\t\t\ttribes: refCard.races?.length ? refCard.races.map((r) => Race[r]) : NO_TRIBES,\r\n\t\t\tisBaconBuddy: refCard.mechanics?.includes(GameTag[GameTag.BACON_BUDDY]) ?? false,\r\n\t\t};\r\n\t\tnativeTribesCache.set(cardId, cached);\r\n\t}\r\n\tconst nativeTribes = cached.tribes;\r\n\tif (anomalies?.length) {\r\n\t\tif (!nativeTribes.length && anomalies.includes(CardIds.IncubationMutation_BG31_Anomaly_112)) {\r\n\t\t\treturn ALL_TRIBES;\r\n\t\t}\r\n\t\tif (cached.isBaconBuddy && anomalies.includes(CardIds.ColorfulCamaraderie_BG33_Anomaly_005)) {\r\n\t\t\treturn ALL_TRIBES;\r\n\t\t}\r\n\t}\r\n\t// The Amalgamation Dark Gift grants all minion types, and is an enchantment rather than a card change\r\n\tif (\r\n\t\tentity.enchantments?.some(\r\n\t\t\t(e) => e.cardId === CardIds.Amalgamation_AmalgamationEnchantment_BG36_MidGameEffect_000t22e,\r\n\t\t)\r\n\t) {\r\n\t\treturn ALL_TRIBES;\r\n\t}\r\n\tconst specialTribes = getSpecialTribesForEntity(entity, playerEntity, allCards);\r\n\tif (!specialTribes.length) {\r\n\t\treturn nativeTribes;\r\n\t}\r\n\treturn [...nativeTribes, ...specialTribes];\r\n};\r\n\r\nconst getSpecialTribesForEntity = (\r\n\tentity: BoardEntity,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n): readonly Race[] => {\r\n\tswitch (entity.cardId) {\r\n\t\tcase CardIds.WhelpSmuggler_BG21_013:\r\n\t\tcase CardIds.WhelpSmuggler_BG21_013_G:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.SmugglerPortrait_BG30_MagicItem_825)\r\n\t\t\t\t? [Race.DRAGON]\r\n\t\t\t\t: NO_TRIBES;\r\n\t\tcase CardIds.LightfangEnforcer_BGS_009:\r\n\t\tcase CardIds.LightfangEnforcer_TB_BaconUps_082:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.EnforcerPortrait_BG30_MagicItem_971)\r\n\t\t\t\t? ALL_TRIBES\r\n\t\t\t\t: NO_TRIBES;\r\n\t\tcase CardIds.BrannBronzebeard_BG_LOE_077:\r\n\t\tcase CardIds.BrannBronzebeard_TB_BaconUps_045:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.BronzebeardPortrait_BG30_MagicItem_418)\r\n\t\t\t\t? [Race.DRAGON, Race.MURLOC]\r\n\t\t\t\t: NO_TRIBES;\r\n\t\tcase CardIds.DrakkariEnchanter_BG26_ICC_901:\r\n\t\tcase CardIds.DrakkariEnchanter_BG26_ICC_901_G:\r\n\t\t\treturn playerEntity.trinkets.some((t) => t.cardId === CardIds.DrakkariPortrait_BG32_MagicItem_179)\r\n\t\t\t\t? [Race.MECH, Race.ELEMENTAL]\r\n\t\t\t\t: NO_TRIBES;\r\n\t}\r\n\treturn NO_TRIBES;\r\n};\r\n\r\n/** @deprecated use hasCorreectTribe instead */\r\nexport const isCorrectTribe = (cardRaces: readonly string[], targetTribe: Race): boolean => {\r\n\tif (!cardRaces?.length) {\r\n\t\treturn false;\r\n\t}\r\n\treturn cardRaces\r\n\t\t.map((cardRace) => getRaceEnum(cardRace))\r\n\t\t.some((raceEnum) => raceEnum === Race.ALL || raceEnum === targetTribe);\r\n};\r\n\r\nexport const getRaceEnum = (race: string): Race => {\r\n\treturn Race[race];\r\n};\r\n\r\nconst IMMUNE_WHEN_ATTACK_IDS = new Set<string>([\r\n\tCardIds.Warpwing_BG24_004,\r\n\tCardIds.Warpwing_BG24_004_G,\r\n\tCardIds.KerriganQueenOfBlades_ViperToken_BG31_HERO_811t8,\r\n\tCardIds.Viper_BG31_HERO_811t8_G,\r\n\tCardIds.TimewarpedViper_BG34_Treasure_990,\r\n\tCardIds.TimewarpedViper_BG34_Treasure_990_G,\r\n]);\r\nconst THREE_CHARGES_IDS = new Set<string>([\r\n\t// CardIds.MarineMatriarch_BG29_610,\r\n\t// CardIds.MarineMatriarch_BG29_610_G,\r\n\t// CardIds.SoftHeartedSiren_BG26_590,\r\n\t// CardIds.SoftHeartedSiren_BG26_590_G,\r\n\t// CardIds.LongJohnCopper_BG29_831,\r\n\t// CardIds.LongJohnCopper_BG29_831_G,\r\n\t// CardIds.BristlingBuffoon_BG29_160,\r\n\t// CardIds.BristlingBuffoon_BG29_160_G,\r\n]);\r\nconst TWO_CHARGES_IDS = new Set<string>([\r\n\tCardIds.Mannoroth_BG27_507_G,\r\n\tCardIds.EclipsionIllidari_TB_BaconShop_HERO_08_Buddy_G,\r\n\tCardIds.MadMatador_BG28_404_G,\r\n\tCardIds.WingedChimera_BG29_844,\r\n\tCardIds.WingedChimera_BG29_844_G,\r\n\tCardIds.MossOfTheSchloss_BG30_111_G,\r\n]);\r\n\r\nexport const addImpliedMechanics = (entity: BoardEntity, cardsData: CardsData): BoardEntity => {\r\n\tentity.cleave = CLEAVE_IDS.has(entity.cardId);\r\n\tentity.cantAttack = CANT_ATTACK_IDS.has(entity.cardId);\r\n\tentity.divineShield = entity.divineShield || entity.hadDivineShield;\r\n\tif (\r\n\t\tentity.enchantments?.some(\r\n\t\t\t(e) => e.cardId === CardIds.TorethsBlessing_TorethsBlessingEnchantment_BG36_MidGameEffect_000t15e,\r\n\t\t)\r\n\t) {\r\n\t\tentity.divineShield = true;\r\n\t\tentity.extraDivineShieldCharges = (entity.extraDivineShieldCharges ?? 0) + extraHits;\r\n\t}\r\n\tentity.immuneWhenAttackCharges = IMMUNE_WHEN_ATTACK_IDS.has(entity.cardId) ? 99999 : null;\r\n\tentity.frenzyChargesLeft =\r\n\t\tentity.cardId === CardIds.BristlebackKnight_BG20_204_G\r\n\t\t\t? 2\r\n\t\t\t: entity.cardId === CardIds.BristlebackKnight_BG20_204\r\n\t\t\t? 1\r\n\t\t\t: 0;\r\n\t// It's not an issue adding a charge for entities without a special ability\r\n\tconst defaultChargesImpl = cardMappings[entity.cardId];\r\n\tif (hasDefaultCharges(defaultChargesImpl)) {\r\n\t\tentity.abiityChargesLeft = defaultChargesImpl.defaultCharges(entity);\r\n\t} else {\r\n\t\tentity.abiityChargesLeft = THREE_CHARGES_IDS.has(entity.cardId)\r\n\t\t\t? 3\r\n\t\t\t: TWO_CHARGES_IDS.has(entity.cardId)\r\n\t\t\t? 2\r\n\t\t\t: 1;\r\n\t}\r\n\r\n\treturn setImplicitDataForEntity(entity, cardsData);\r\n};\r\n\r\nconst setImplicitDataForEntity = (entity: BoardEntity, cardsData: CardsData): BoardEntity => {\r\n\tentity.cardId = normalizeCardIdForSkin(entity.cardId);\r\n\tentity.maxHealth = Math.max(0, entity.health, entity.maxHealth ?? 0);\r\n\tentity.maxAttack = Math.max(0, entity.attack, entity.maxAttack ?? 0);\r\n\tconst avengeValue = cardsData.avengeValue(entity.cardId);\r\n\tif (avengeValue > 0) {\r\n\t\tentity.avengeCurrent = avengeValue;\r\n\t\tentity.avengeDefault = avengeValue;\r\n\t}\r\n\treturn entity;\r\n};\r\n\r\nexport const normalizeCardIdForSkin = (cardId: string): string => {\r\n\tif (!cardId?.length) {\r\n\t\treturn cardId;\r\n\t}\r\n\t// Quick check to avoid the regex allocation in the (very common) non-skin case\r\n\t// lastIndexOf to mirror the greedy behavior of the previous /(.*)_SKIN_.*/ regex\r\n\tconst skinIndex = cardId.lastIndexOf('_SKIN_');\r\n\tif (skinIndex === -1) {\r\n\t\treturn cardId;\r\n\t}\r\n\treturn cardId.slice(0, skinIndex);\r\n};\r\n\r\nexport const stringifySimple = (board: readonly BoardEntity[], allCards: AllCardsService = null): string => {\r\n\treturn '[' + board.map((entity) => stringifySimpleCard(entity, allCards)).join(', ') + ']';\r\n};\r\n\r\nexport const stringifySimpleCard = (entity: BoardEntity, allCards: AllCardsService = null): string => {\r\n\treturn entity\r\n\t\t? `${allCards?.getCard(entity.cardId)?.name ?? entity.cardId}/entityId=${entity.entityId}/atk=${\r\n\t\t\t\tentity.attack\r\n\t\t }/hp=${entity.health}/ench=${entity.enchantments.map((e) => e.cardId).join(',')}`\r\n\t\t: null;\r\n};\r\n\r\nexport const isFish = (entity: BoardEntity): boolean => {\r\n\treturn (\r\n\t\tentity.cardId?.startsWith(CardIds.AvatarOfNzoth_FishOfNzothToken) ||\r\n\t\tentity.cardId?.startsWith(CardIds.FishOfNzoth)\r\n\t);\r\n};\r\n\r\nexport const isPilotedWhirlOTron = (entity: BoardEntity): boolean => {\r\n\treturn entity.cardId?.startsWith(CardIds.PilotedWhirlOTron_BG21_HERO_030_Buddy);\r\n};\r\n\r\nexport const isGolden = (cardId: string, allCards: AllCardsService): boolean => {\r\n\treturn allCards.getCard(cardId).premium;\r\n};\r\n\r\nexport const isBoardEntity = (entity: BoardEntity | BoardTrinket | BgsPlayerEntity): entity is BoardEntity => {\r\n\treturn entity != null && 'maxHealth' in entity;\r\n};\r\n\r\nexport const getPlayerState = (gameState: GameState, hero: BgsPlayerEntity): PlayerState => {\r\n\treturn gameState.player.player === hero\r\n\t\t? gameState.player\r\n\t\t: gameState.player.teammate?.player === hero\r\n\t\t? gameState.player.teammate\r\n\t\t: gameState.opponent.player === hero\r\n\t\t? gameState.opponent\r\n\t\t: gameState.opponent.teammate?.player === hero\r\n\t\t? gameState.opponent.teammate\r\n\t\t: null;\r\n};\r\n\r\nexport const getTeammateInitialState = (gameState: GameState, hero: BgsPlayerEntity): PlayerState => {\r\n\treturn gameState.playerInitial.player?.entityId === hero?.entityId\r\n\t\t? gameState.playerInitial.teammate\r\n\t\t: gameState.playerInitial.teammate?.player?.entityId === hero?.entityId\r\n\t\t? gameState.playerInitial\r\n\t\t: gameState.opponentInitial.player?.entityId === hero?.entityId\r\n\t\t? gameState.opponentInitial.teammate\r\n\t\t: gameState.opponentInitial.teammate?.player?.entityId === hero?.entityId\r\n\t\t? gameState.opponentInitial\r\n\t\t: null;\r\n};\r\n\r\nexport const getTeamInitialStates = (gameState: GameState, hero: BgsPlayerEntity): PlayerState[] => {\r\n\treturn gameState.playerInitial.player?.friendly === hero?.friendly\r\n\t\t? [gameState.playerInitial, gameState.playerInitial.teammate].filter((p) => p)\r\n\t\t: [gameState.opponentInitial, gameState.opponentInitial.teammate].filter((p) => p);\r\n};\r\n\r\nexport const getPlayerInitialState = (gameState: GameState, hero: BgsPlayerEntity): PlayerState => {\r\n\treturn gameState.playerInitial.player?.friendly === hero?.friendly\r\n\t\t? gameState.playerInitial\r\n\t\t: gameState.opponentInitial;\r\n};\r\n\r\nexport const copyEntity = (entity: BoardEntity): BoardEntity => {\r\n\tconst copy: BoardEntity = {\r\n\t\t...entity,\r\n\t\tenchantments: (entity.enchantments ?? []).map((ench) => ({ ...ench })),\r\n\t\tpendingAttackBuffs: [],\r\n\t\trememberedDeathrattles: (entity.rememberedDeathrattles ?? []).map((r) => ({ ...r })),\r\n\t\tadditionalCards: entity.additionalCards?.map((c) => c),\r\n\t\ttags: entity.tags ? { ...entity.tags } : null,\r\n\t\tlastAffectedByEntity: null,\r\n\t};\r\n\treturn copy;\r\n};\r\n\r\nexport const isDead = (entity: BoardEntity): boolean => {\r\n\treturn entity.health <= 0 || entity.definitelyDead;\r\n};\r\n"]}
|