@firestone-hs/simulate-bgs-battle 1.1.548 → 1.1.550
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/board-entity.d.ts +4 -0
- package/dist/board-entity.js.map +1 -1
- package/dist/cards/impl/anomaly/anomalous-twin.js +1 -1
- package/dist/cards/impl/anomaly/anomalous-twin.js.map +1 -1
- package/dist/cards/impl/bg-spell/toxic-tumbleweed.js +1 -1
- package/dist/cards/impl/bg-spell/toxic-tumbleweed.js.map +1 -1
- package/dist/cards/impl/hero-power/embrace-your-rage.js +1 -1
- package/dist/cards/impl/hero-power/embrace-your-rage.js.map +1 -1
- package/dist/cards/impl/minion/battlecruiser.js +6 -7
- package/dist/cards/impl/minion/battlecruiser.js.map +1 -1
- package/dist/cards/impl/minion/captain-bonerender.js +1 -1
- package/dist/cards/impl/minion/captain-bonerender.js.map +1 -1
- package/dist/cards/impl/minion/carbonic-copy.js +1 -1
- package/dist/cards/impl/minion/carbonic-copy.js.map +1 -1
- package/dist/cards/impl/minion/carrier.js +3 -1
- package/dist/cards/impl/minion/carrier.js.map +1 -1
- package/dist/cards/impl/minion/diremuck-forager.js +1 -1
- package/dist/cards/impl/minion/diremuck-forager.js.map +1 -1
- package/dist/cards/impl/minion/salty-hog.js +2 -1
- package/dist/cards/impl/minion/salty-hog.js.map +1 -1
- package/dist/cards/impl/minion/stitched-salvager.js +14 -3
- package/dist/cards/impl/minion/stitched-salvager.js.map +1 -1
- package/dist/cards/impl/minion/zergling.js +1 -1
- package/dist/cards/impl/minion/zergling.js.map +1 -1
- package/dist/cards/impl/quest-reward/evil-twin.js +1 -1
- package/dist/cards/impl/quest-reward/evil-twin.js.map +1 -1
- package/dist/cards/impl/trinket/automaton-portrait.js +1 -1
- package/dist/cards/impl/trinket/automaton-portrait.js.map +1 -1
- package/dist/cards/impl/trinket/fishy-sticker.js +1 -1
- package/dist/cards/impl/trinket/fishy-sticker.js.map +1 -1
- package/dist/cards/impl/trinket/karazhan-chess-set.js +1 -1
- package/dist/cards/impl/trinket/karazhan-chess-set.js.map +1 -1
- package/dist/cards/impl/trinket/ship-in-a-bottle.js +1 -1
- package/dist/cards/impl/trinket/ship-in-a-bottle.js.map +1 -1
- package/dist/cards/impl/trinket/summoning-sphere.js +1 -1
- package/dist/cards/impl/trinket/summoning-sphere.js.map +1 -1
- package/dist/keywords/divine-shield.js +4 -4
- package/dist/keywords/divine-shield.js.map +1 -1
- package/dist/simulation/after-attack.js +2 -0
- package/dist/simulation/after-attack.js.map +1 -1
- package/dist/simulation/attack.js +2 -2
- package/dist/simulation/attack.js.map +1 -1
- package/dist/simulation/avenge.js +2 -2
- package/dist/simulation/avenge.js.map +1 -1
- package/dist/simulation/battlecries.js +2 -2
- package/dist/simulation/battlecries.js.map +1 -1
- package/dist/simulation/damage-effects.js +1 -1
- package/dist/simulation/damage-effects.js.map +1 -1
- package/dist/simulation/death-effects.js +2 -2
- package/dist/simulation/death-effects.js.map +1 -1
- package/dist/simulation/deathrattle-effects.js +8 -4
- package/dist/simulation/deathrattle-effects.js.map +1 -1
- package/dist/simulation/deathrattle-orchestration.js +6 -1
- package/dist/simulation/deathrattle-orchestration.js.map +1 -1
- package/dist/simulation/deathrattle-spawns.d.ts +1 -5
- package/dist/simulation/deathrattle-spawns.js +75 -75
- package/dist/simulation/deathrattle-spawns.js.map +1 -1
- package/dist/simulation/minion-death.js +1 -1
- package/dist/simulation/minion-death.js.map +1 -1
- package/dist/simulation/on-attack.js +0 -2
- package/dist/simulation/on-attack.js.map +1 -1
- package/dist/simulation/reborn.js +1 -1
- package/dist/simulation/reborn.js.map +1 -1
- package/dist/simulation/secrets.js +4 -4
- package/dist/simulation/secrets.js.map +1 -1
- package/dist/simulation/start-of-combat/soc-illidan-hero-power.js +0 -1
- package/dist/simulation/start-of-combat/soc-illidan-hero-power.js.map +1 -1
- package/dist/simulation/stats.js +2 -4
- package/dist/simulation/stats.js.map +1 -1
- package/dist/simulation/summon-when-space.js +3 -3
- package/dist/simulation/summon-when-space.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ exports.ShipInABottle = {
|
|
|
10
10
|
if (input.playerBoard.length < 7) {
|
|
11
11
|
const target = (0, utils_1.pickRandom)(input.gameState.cardsData.pirateSpawns);
|
|
12
12
|
(0, cards_in_hand_1.addCardsInHand)(input.playerEntity, input.playerBoard, [target], input.gameState);
|
|
13
|
-
const newMinions = (0, deathrattle_spawns_1.spawnEntities)(target, 1, input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState
|
|
13
|
+
const newMinions = (0, deathrattle_spawns_1.spawnEntities)(target, 1, input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState, input.playerEntity.friendly, false);
|
|
14
14
|
const spawns = (0, spawns_1.performEntitySpawns)(newMinions, input.playerBoard, input.playerEntity, input.playerEntity, 0, input.opponentBoard, input.opponentEntity, input.gameState);
|
|
15
15
|
spawns.forEach((spawn) => (spawn.attackImmediately = true));
|
|
16
16
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ship-in-a-bottle.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/ship-in-a-bottle.ts"],"names":[],"mappings":";;;AACA,mDAAqD;AACrD,qEAAmE;AACnE,+EAAuE;AACvE,uDAAiE;AAGpD,QAAA,aAAa,GAAG;IAC5B,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;YACjC,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAClE,IAAA,8BAAc,EAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YACjF,MAAM,UAAU,GAAG,IAAA,kCAAa,EAC/B,MAAM,EACN,CAAC,EACD,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"ship-in-a-bottle.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/ship-in-a-bottle.ts"],"names":[],"mappings":";;;AACA,mDAAqD;AACrD,qEAAmE;AACnE,+EAAuE;AACvE,uDAAiE;AAGpD,QAAA,aAAa,GAAG;IAC5B,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;QACzD,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;YACjC,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAClE,IAAA,8BAAc,EAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YACjF,MAAM,UAAU,GAAG,IAAA,kCAAa,EAC/B,MAAM,EACN,CAAC,EACD,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,YAAY,CAAC,QAAQ,EAC3B,KAAK,CACL,CAAC;YACF,MAAM,MAAM,GAAG,IAAA,4BAAmB,EACjC,UAAU,EACV,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,YAAY,EAClB,CAAC,EACD,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;YACF,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC,CAAC;YAC5D,OAAO,IAAI,CAAC;SACZ;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { pickRandom } from '../../../services/utils';\r\nimport { addCardsInHand } from '../../../simulation/cards-in-hand';\r\nimport { spawnEntities } from '../../../simulation/deathrattle-spawns';\r\nimport { performEntitySpawns } from '../../../simulation/spawns';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\n\r\nexport const ShipInABottle = {\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tif (input.playerBoard.length < 7) {\r\n\t\t\tconst target = pickRandom(input.gameState.cardsData.pirateSpawns);\r\n\t\t\taddCardsInHand(input.playerEntity, input.playerBoard, [target], input.gameState);\r\n\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\ttarget,\r\n\t\t\t\t1,\r\n\t\t\t\tinput.playerBoard,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tinput.opponentBoard,\r\n\t\t\t\tinput.opponentEntity,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t\tinput.playerEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t);\r\n\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\tnewMinions,\r\n\t\t\t\tinput.playerBoard,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\t0,\r\n\t\t\t\tinput.opponentBoard,\r\n\t\t\t\tinput.opponentEntity,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t\tspawns.forEach((spawn) => (spawn.attackImmediately = true));\r\n\t\t\treturn true;\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
|
@@ -20,7 +20,7 @@ exports.SummoningSphere = {
|
|
|
20
20
|
definitelyDead: false,
|
|
21
21
|
attackImmediately: false,
|
|
22
22
|
}, input.gameState.cardsData);
|
|
23
|
-
const newMinions = (0, deathrattle_spawns_1.spawnEntities)(clone.cardId, 1, input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState
|
|
23
|
+
const newMinions = (0, deathrattle_spawns_1.spawnEntities)(clone.cardId, 1, input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState, highestHealthMinion.friendly, true, false, false, clone);
|
|
24
24
|
const indexFromRight = 0;
|
|
25
25
|
const spawned = (0, spawns_1.performEntitySpawns)(newMinions, input.playerBoard, input.playerEntity, highestHealthMinion, indexFromRight, input.opponentBoard, input.opponentEntity, input.gameState);
|
|
26
26
|
if (spawned.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summoning-sphere.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/summoning-sphere.ts"],"names":[],"mappings":";;;AAEA,mDAAuD;AACvD,+EAAuE;AACvE,uDAAiE;AAEjE,0CAA8E;AAEjE,QAAA,eAAe,GAAG;IAC9B,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;;QACzD,MAAM,aAAa,GAAG,IAAA,+BAAuB,EAAC,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAA,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,KAAK,0CAAE,MAAM,CAAA,EAAE;YAClC,OAAO;SACP;QACD,MAAM,mBAAmB,GAAG,IAAA,oBAAY,EAAC,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1G,MAAM,KAAK,GAAgB,IAAA,2BAAmB,EAC7C;YACC,GAAG,mBAAmB;YACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,eAAe,EAAE;YACvD,oBAAoB,EAAE,IAAI;YAC1B,cAAc,EAAE,KAAK;YACrB,iBAAiB,EAAE,KAAK;SACxB,EACD,KAAK,CAAC,SAAS,CAAC,SAAS,CACzB,CAAC;QACF,MAAM,UAAU,GAAG,IAAA,kCAAa,EAC/B,KAAK,CAAC,MAAM,EACZ,CAAC,EACD,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"summoning-sphere.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/summoning-sphere.ts"],"names":[],"mappings":";;;AAEA,mDAAuD;AACvD,+EAAuE;AACvE,uDAAiE;AAEjE,0CAA8E;AAEjE,QAAA,eAAe,GAAG;IAC9B,aAAa,EAAE,CAAC,OAAqB,EAAE,KAAe,EAAE,EAAE;;QACzD,MAAM,aAAa,GAAG,IAAA,+BAAuB,EAAC,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAA,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,KAAK,0CAAE,MAAM,CAAA,EAAE;YAClC,OAAO;SACP;QACD,MAAM,mBAAmB,GAAG,IAAA,oBAAY,EAAC,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1G,MAAM,KAAK,GAAgB,IAAA,2BAAmB,EAC7C;YACC,GAAG,mBAAmB;YACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,eAAe,EAAE;YACvD,oBAAoB,EAAE,IAAI;YAC1B,cAAc,EAAE,KAAK;YACrB,iBAAiB,EAAE,KAAK;SACxB,EACD,KAAK,CAAC,SAAS,CAAC,SAAS,CACzB,CAAC;QACF,MAAM,UAAU,GAAG,IAAA,kCAAa,EAC/B,KAAK,CAAC,MAAM,EACZ,CAAC,EACD,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EACf,mBAAmB,CAAC,QAAQ,EAC5B,IAAI,EACJ,KAAK,EACL,KAAK,EACL,KAAK,CACL,CAAC;QACF,MAAM,cAAc,GAAG,CAAC,CAAC;QACzB,MAAM,OAAO,GAAG,IAAA,4BAAmB,EAClC,UAAU,EACV,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,mBAAmB,EACnB,cAAc,EACd,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YACvB,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,KAAK,CAAC,YAAY,EAClB,KAAK,EACL,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,cAAc,CACpB,CAAC;YACF,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;SACpE;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { shuffleArray } from '../../../services/utils';\r\nimport { spawnEntities } from '../../../simulation/deathrattle-spawns';\r\nimport { performEntitySpawns } from '../../../simulation/spawns';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { addImpliedMechanics, getTeammateInitialState } from '../../../utils';\r\n\r\nexport const SummoningSphere = {\r\n\tstartOfCombat: (trinket: BoardTrinket, input: SoCInput) => {\r\n\t\tconst teammateState = getTeammateInitialState(input.gameState.gameState, input.playerEntity);\r\n\t\tif (!teammateState?.board?.length) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst highestHealthMinion = shuffleArray([...teammateState.board]).sort((a, b) => b.health - a.health)[0];\r\n\t\tconst clone: BoardEntity = addImpliedMechanics(\r\n\t\t\t{\r\n\t\t\t\t...highestHealthMinion,\r\n\t\t\t\tentityId: input.gameState.sharedState.currentEntityId++,\r\n\t\t\t\tlastAffectedByEntity: null,\r\n\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\tattackImmediately: false,\r\n\t\t\t},\r\n\t\t\tinput.gameState.cardsData,\r\n\t\t);\r\n\t\tconst newMinions = spawnEntities(\r\n\t\t\tclone.cardId,\r\n\t\t\t1,\r\n\t\t\tinput.playerBoard,\r\n\t\t\tinput.playerEntity,\r\n\t\t\tinput.opponentBoard,\r\n\t\t\tinput.opponentEntity,\r\n\t\t\tinput.gameState,\r\n\t\t\thighestHealthMinion.friendly,\r\n\t\t\ttrue,\r\n\t\t\tfalse,\r\n\t\t\tfalse,\r\n\t\t\tclone,\r\n\t\t);\r\n\t\tconst indexFromRight = 0;\r\n\t\tconst spawned = performEntitySpawns(\r\n\t\t\tnewMinions,\r\n\t\t\tinput.playerBoard,\r\n\t\t\tinput.playerEntity,\r\n\t\t\thighestHealthMinion,\r\n\t\t\tindexFromRight,\r\n\t\t\tinput.opponentBoard,\r\n\t\t\tinput.opponentEntity,\r\n\t\t\tinput.gameState,\r\n\t\t);\r\n\t\tif (spawned.length > 0) {\r\n\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tclone,\r\n\t\t\t\tinput.playerBoard,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tinput.opponentEntity,\r\n\t\t\t);\r\n\t\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true };\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
|
@@ -14,14 +14,14 @@ const updateDivineShield = (entity, board, hero, otherHero, newValue, gameState)
|
|
|
14
14
|
entity.divineShield = newValue;
|
|
15
15
|
if (entity.divineShield) {
|
|
16
16
|
const boardForDrake = board;
|
|
17
|
-
const statsBonus =
|
|
18
|
-
|
|
17
|
+
const statsBonus = 6 * boardForDrake.filter((e) => e.cardId === "BG25_043").length +
|
|
18
|
+
12 * boardForDrake.filter((e) => e.cardId === "BG25_043_G").length;
|
|
19
19
|
entity.attack += statsBonus;
|
|
20
20
|
}
|
|
21
21
|
else {
|
|
22
22
|
const boardForDrake = board;
|
|
23
|
-
const statsBonus =
|
|
24
|
-
|
|
23
|
+
const statsBonus = 6 * boardForDrake.filter((e) => e.cardId === "BG25_043").length +
|
|
24
|
+
12 * boardForDrake.filter((e) => e.cardId === "BG25_043_G").length;
|
|
25
25
|
entity.attack -= statsBonus;
|
|
26
26
|
}
|
|
27
27
|
if (entity.hadDivineShield && !entity.divineShield) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"divine-shield.js","sourceRoot":"","sources":["../../src/keywords/divine-shield.ts"],"names":[],"mappings":"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","sourcesContent":["import { CardIds, CardType, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnDivineShieldUpdated } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { pickRandom } from '../services/utils';\r\nimport { addCardsInHand } from '../simulation/cards-in-hand';\r\nimport { FullGameState } from '../simulation/internal-game-state';\r\nimport { modifyStats } from '../simulation/stats';\r\nimport { grantRandomStats, hasCorrectTribe } from '../utils';\r\n\r\nexport const updateDivineShield = (\r\n\tentity: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tnewValue: boolean,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// if ((entity.divineShield ?? false) === newValue) {\r\n\t// \treturn;\r\n\t// }\r\n\tentity.hadDivineShield = newValue || entity.divineShield || entity.hadDivineShield;\r\n\tentity.divineShield = newValue;\r\n\tif (entity.divineShield) {\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t8 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t16 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\t// Don't trigger all \"on attack changed\" effects, since it's an aura\r\n\t\tentity.attack += statsBonus;\r\n\t} else {\r\n\t\t// Also consider itself\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t8 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t16 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\tentity.attack -= statsBonus;\r\n\t}\r\n\r\n\t// Lost divine shield\r\n\tif (entity.hadDivineShield && !entity.divineShield) {\r\n\t\tconst adapter = hero.trinkets\r\n\t\t\t.filter((t) => t.cardId === CardIds.MechagonAdapter_BG30_MagicItem_910)\r\n\t\t\t.filter((t) => t.scriptDataNum1 > 0)[0];\r\n\t\tif (!!adapter && hasCorrectTribe(entity, hero, Race.MECH, gameState.allCards)) {\r\n\t\t\tupdateDivineShield(entity, board, hero, otherHero, true, gameState);\r\n\t\t\tadapter.scriptDataNum1--;\r\n\t\t}\r\n\r\n\t\tfor (const boardEntity of board) {\r\n\t\t\tconst onDivineShieldUpdatedImpl = cardMappings[boardEntity.cardId];\r\n\t\t\tif (hasOnDivineShieldUpdated(onDivineShieldUpdatedImpl)) {\r\n\t\t\t\tonDivineShieldUpdatedImpl.onDivineShieldUpdated(boardEntity, {\r\n\t\t\t\t\tboard: board,\r\n\t\t\t\t\thero: hero,\r\n\t\t\t\t\totherHero: otherHero,\r\n\t\t\t\t\tgameState: gameState,\r\n\t\t\t\t\ttarget: entity,\r\n\t\t\t\t\tpreviousValue: entity.hadDivineShield,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfor (let i = 0; i < board.length; i++) {\r\n\t\t\tif (board[i].cardId === CardIds.BolvarFireblood_ICC_858) {\r\n\t\t\t\tmodifyStats(board[i], 2, 0, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (board[i].cardId === CardIds.BolvarFireblood_TB_BaconUps_047) {\r\n\t\t\t\tmodifyStats(board[i], 4, 0, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (board[i].cardId === CardIds.DrakonidEnforcer_BGS_067) {\r\n\t\t\t\tmodifyStats(board[i], 2, 2, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (board[i].cardId === CardIds.DrakonidEnforcer_TB_BaconUps_117) {\r\n\t\t\t\tmodifyStats(board[i], 4, 4, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (\r\n\t\t\t\tboard[i].entityId !== entity.entityId &&\r\n\t\t\t\t(board[i].cardId === CardIds.HolyMecherel_BG20_401 ||\r\n\t\t\t\t\tboard[i].cardId === CardIds.HolyMecherel_BG20_401_G)\r\n\t\t\t) {\r\n\t\t\t\tupdateDivineShield(board[i], board, hero, otherHero, true, gameState);\r\n\t\t\t} else if (board[i].cardId === CardIds.Gemsplitter_BG21_037) {\r\n\t\t\t\taddCardsInHand(hero, board, [CardIds.BloodGem], gameState);\r\n\t\t\t} else if (board[i].cardId === CardIds.Gemsplitter_BG21_037_G) {\r\n\t\t\t\taddCardsInHand(hero, board, [CardIds.BloodGem, CardIds.BloodGem], gameState);\r\n\t\t\t} else if (\r\n\t\t\t\tboard[i].cardId === CardIds.CogworkCopter_BG24_008 ||\r\n\t\t\t\tboard[i].cardId === CardIds.CogworkCopter_BG24_008_G\r\n\t\t\t) {\r\n\t\t\t\t// When it's the opponent, the game state already contains all the buffs\r\n\t\t\t\tif (board[i]?.friendly) {\r\n\t\t\t\t\tconst buff = board[i].cardId === CardIds.CogworkCopter_BG24_008_G ? 2 : 1;\r\n\t\t\t\t\tgrantRandomStats(\r\n\t\t\t\t\t\tboard[i],\r\n\t\t\t\t\t\thero.hand.filter(\r\n\t\t\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t\t\tgameState.allCards.getCard(e.cardId).type?.toUpperCase() === CardType[CardType.MINION],\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t\thero,\r\n\t\t\t\t\t\tbuff,\r\n\t\t\t\t\t\tbuff,\r\n\t\t\t\t\t\tnull,\r\n\t\t\t\t\t\ttrue,\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\r\nexport const grantRandomDivineShield = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst elligibleEntities = board\r\n\t\t.filter((entity) => !entity.divineShield)\r\n\t\t.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\tif (elligibleEntities.length > 0) {\r\n\t\tconst chosen = pickRandom(elligibleEntities);\r\n\t\tupdateDivineShield(chosen, board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, chosen, board, null, null);\r\n\t}\r\n};\r\n\r\nexport const grantDivineShieldToLeftmostMinions = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tquantity: number,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tfor (let i = 0; i < Math.min(quantity, board.length); i++) {\r\n\t\tupdateDivineShield(board[i], board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, board[i], board, null, null);\r\n\t}\r\n};\r\n\r\nexport interface OnDivineShieldUpdatedInput {\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n\ttarget: BoardEntity;\r\n\tpreviousValue: boolean;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"divine-shield.js","sourceRoot":"","sources":["../../src/keywords/divine-shield.ts"],"names":[],"mappings":"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","sourcesContent":["import { CardIds, CardType, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnDivineShieldUpdated } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { pickRandom } from '../services/utils';\r\nimport { addCardsInHand } from '../simulation/cards-in-hand';\r\nimport { FullGameState } from '../simulation/internal-game-state';\r\nimport { modifyStats } from '../simulation/stats';\r\nimport { grantRandomStats, hasCorrectTribe } from '../utils';\r\n\r\nexport const updateDivineShield = (\r\n\tentity: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tnewValue: boolean,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// if ((entity.divineShield ?? false) === newValue) {\r\n\t// \treturn;\r\n\t// }\r\n\tentity.hadDivineShield = newValue || entity.divineShield || entity.hadDivineShield;\r\n\tentity.divineShield = newValue;\r\n\tif (entity.divineShield) {\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t6 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t12 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\t// Don't trigger all \"on attack changed\" effects, since it's an aura\r\n\t\tentity.attack += statsBonus;\r\n\t} else {\r\n\t\t// Also consider itself\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t6 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t12 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\tentity.attack -= statsBonus;\r\n\t}\r\n\r\n\t// Lost divine shield\r\n\tif (entity.hadDivineShield && !entity.divineShield) {\r\n\t\tconst adapter = hero.trinkets\r\n\t\t\t.filter((t) => t.cardId === CardIds.MechagonAdapter_BG30_MagicItem_910)\r\n\t\t\t.filter((t) => t.scriptDataNum1 > 0)[0];\r\n\t\tif (!!adapter && hasCorrectTribe(entity, hero, Race.MECH, gameState.allCards)) {\r\n\t\t\tupdateDivineShield(entity, board, hero, otherHero, true, gameState);\r\n\t\t\tadapter.scriptDataNum1--;\r\n\t\t}\r\n\r\n\t\tfor (const boardEntity of board) {\r\n\t\t\tconst onDivineShieldUpdatedImpl = cardMappings[boardEntity.cardId];\r\n\t\t\tif (hasOnDivineShieldUpdated(onDivineShieldUpdatedImpl)) {\r\n\t\t\t\tonDivineShieldUpdatedImpl.onDivineShieldUpdated(boardEntity, {\r\n\t\t\t\t\tboard: board,\r\n\t\t\t\t\thero: hero,\r\n\t\t\t\t\totherHero: otherHero,\r\n\t\t\t\t\tgameState: gameState,\r\n\t\t\t\t\ttarget: entity,\r\n\t\t\t\t\tpreviousValue: entity.hadDivineShield,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfor (let i = 0; i < board.length; i++) {\r\n\t\t\tif (board[i].cardId === CardIds.BolvarFireblood_ICC_858) {\r\n\t\t\t\tmodifyStats(board[i], 2, 0, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (board[i].cardId === CardIds.BolvarFireblood_TB_BaconUps_047) {\r\n\t\t\t\tmodifyStats(board[i], 4, 0, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (board[i].cardId === CardIds.DrakonidEnforcer_BGS_067) {\r\n\t\t\t\tmodifyStats(board[i], 2, 2, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (board[i].cardId === CardIds.DrakonidEnforcer_TB_BaconUps_117) {\r\n\t\t\t\tmodifyStats(board[i], 4, 4, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t} else if (\r\n\t\t\t\tboard[i].entityId !== entity.entityId &&\r\n\t\t\t\t(board[i].cardId === CardIds.HolyMecherel_BG20_401 ||\r\n\t\t\t\t\tboard[i].cardId === CardIds.HolyMecherel_BG20_401_G)\r\n\t\t\t) {\r\n\t\t\t\tupdateDivineShield(board[i], board, hero, otherHero, true, gameState);\r\n\t\t\t} else if (board[i].cardId === CardIds.Gemsplitter_BG21_037) {\r\n\t\t\t\taddCardsInHand(hero, board, [CardIds.BloodGem], gameState);\r\n\t\t\t} else if (board[i].cardId === CardIds.Gemsplitter_BG21_037_G) {\r\n\t\t\t\taddCardsInHand(hero, board, [CardIds.BloodGem, CardIds.BloodGem], gameState);\r\n\t\t\t} else if (\r\n\t\t\t\tboard[i].cardId === CardIds.CogworkCopter_BG24_008 ||\r\n\t\t\t\tboard[i].cardId === CardIds.CogworkCopter_BG24_008_G\r\n\t\t\t) {\r\n\t\t\t\t// When it's the opponent, the game state already contains all the buffs\r\n\t\t\t\tif (board[i]?.friendly) {\r\n\t\t\t\t\tconst buff = board[i].cardId === CardIds.CogworkCopter_BG24_008_G ? 2 : 1;\r\n\t\t\t\t\tgrantRandomStats(\r\n\t\t\t\t\t\tboard[i],\r\n\t\t\t\t\t\thero.hand.filter(\r\n\t\t\t\t\t\t\t(e) =>\r\n\t\t\t\t\t\t\t\tgameState.allCards.getCard(e.cardId).type?.toUpperCase() === CardType[CardType.MINION],\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\t\thero,\r\n\t\t\t\t\t\tbuff,\r\n\t\t\t\t\t\tbuff,\r\n\t\t\t\t\t\tnull,\r\n\t\t\t\t\t\ttrue,\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\r\nexport const grantRandomDivineShield = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst elligibleEntities = board\r\n\t\t.filter((entity) => !entity.divineShield)\r\n\t\t.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\tif (elligibleEntities.length > 0) {\r\n\t\tconst chosen = pickRandom(elligibleEntities);\r\n\t\tupdateDivineShield(chosen, board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, chosen, board, null, null);\r\n\t}\r\n};\r\n\r\nexport const grantDivineShieldToLeftmostMinions = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tquantity: number,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tfor (let i = 0; i < Math.min(quantity, board.length); i++) {\r\n\t\tupdateDivineShield(board[i], board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, board[i], board, null, null);\r\n\t}\r\n};\r\n\r\nexport interface OnDivineShieldUpdatedInput {\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n\ttarget: BoardEntity;\r\n\tpreviousValue: boolean;\r\n}\r\n"]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.applyAfterAttackEffects = void 0;
|
|
4
4
|
const reference_data_1 = require("@firestone-hs/reference-data");
|
|
5
|
+
const stealth_1 = require("../keywords/stealth");
|
|
5
6
|
const utils_1 = require("../utils");
|
|
6
7
|
const blood_gems_1 = require("./blood-gems");
|
|
7
8
|
const cards_in_hand_1 = require("./cards-in-hand");
|
|
@@ -11,6 +12,7 @@ const quest_1 = require("./quest");
|
|
|
11
12
|
const stats_1 = require("./stats");
|
|
12
13
|
const applyAfterAttackEffects = (attackingEntity, attackingBoard, attackingBoardHero, defendingEntity, defendingBoardHero, damageDoneByAttacker, damageDoneByDefender, gameState) => {
|
|
13
14
|
var _a, _b;
|
|
15
|
+
(0, stealth_1.updateStealth)(attackingEntity, false, attackingBoard, attackingBoardHero, defendingBoardHero, gameState);
|
|
14
16
|
let secretTriggered = null;
|
|
15
17
|
if ((secretTriggered = (_a = defendingBoardHero.secrets) === null || _a === void 0 ? void 0 : _a.find((secret) => !secret.triggered && (secret === null || secret === void 0 ? void 0 : secret.cardId) === "TB_Bacon_Secrets_14")) != null) {
|
|
16
18
|
if (damageDoneByAttacker >= 3 && !(attackingEntity.health <= 0 || attackingEntity.definitelyDead)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"after-attack.js","sourceRoot":"","sources":["../../src/simulation/after-attack.ts"],"names":[],"mappings":"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","sourcesContent":["import { CardIds, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { grantStatsToMinionsOfEachType, hasCorrectTribe } from '../utils';\r\nimport { playBloodGemsOn } from './blood-gems';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { processDeathrattleForMinion } from './deathrattle-orchestration';\r\nimport { getValidDeathrattles } from './deathrattle-utils';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { onQuestProgressUpdated } from './quest';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const applyAfterAttackEffects = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tdamageDoneByAttacker: number,\r\n\tdamageDoneByDefender: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tlet secretTriggered = null;\r\n\tif (\r\n\t\t(secretTriggered = defendingBoardHero.secrets?.find(\r\n\t\t\t(secret) => !secret.triggered && secret?.cardId === CardIds.Reckoning_TB_Bacon_Secrets_14,\r\n\t\t)) != null\r\n\t) {\r\n\t\t// console.log('triggering secret?', damageDoneByAttacker, stringifySimpleCard(attackingEntity, allCards));\r\n\t\tif (damageDoneByAttacker >= 3 && !(attackingEntity.health <= 0 || attackingEntity.definitelyDead)) {\r\n\t\t\tsecretTriggered.triggered = true;\r\n\t\t\tattackingEntity.definitelyDead = true;\r\n\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\tsecretTriggered,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\tif (attackingEntity.cardId === CardIds.Bonker_BG20_104 || attackingEntity.cardId === CardIds.Bonker_BG20_104_G) {\r\n\t\tconst quantity = attackingEntity.cardId === CardIds.Bonker_BG20_104_G ? 2 : 1;\r\n\t\tconst cards = quantity === 1 ? [CardIds.BloodGem] : [CardIds.BloodGem, CardIds.BloodGem];\r\n\t\taddCardsInHand(attackingBoardHero, attackingBoard, cards, gameState);\r\n\t} else if (attackingEntity.cardId === CardIds.Yrel_BG23_350 || attackingEntity.cardId === CardIds.Yrel_BG23_350_G) {\r\n\t\tconst modifier = attackingEntity.cardId === CardIds.Yrel_BG23_350_G ? 2 : 1;\r\n\t\tgrantStatsToMinionsOfEachType(\r\n\t\t\tattackingEntity,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tmodifier * 1,\r\n\t\t\tmodifier * 2,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.IncorporealCorporal_BG26_RLK_117 ||\r\n\t\tattackingEntity.cardId === CardIds.IncorporealCorporal_BG26_RLK_117_G\r\n\t) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.MonstrousMacaw_BGS_078 ||\r\n\t\tattackingEntity.cardId === CardIds.MonstrousMacaw_TB_BaconUps_135\r\n\t) {\r\n\t\tconst loops = attackingEntity.cardId === CardIds.MonstrousMacaw_TB_BaconUps_135 ? 2 : 1;\r\n\t\tconst targetBoard = attackingBoard.filter((e) => e.entityId !== attackingEntity.entityId);\r\n\t\tconst validDeathrattles = getValidDeathrattles(targetBoard, gameState);\r\n\t\tconst leftMost = validDeathrattles[0];\r\n\t\tif (!!leftMost) {\r\n\t\t\tfor (let i = 0; i < loops; i++) {\r\n\t\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\tleftMost,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t);\r\n\t\t\t\tconst indexFromRight = attackingBoard.length - (attackingBoard.indexOf(leftMost) + 1);\r\n\t\t\t\tprocessDeathrattleForMinion(\r\n\t\t\t\t\tleftMost,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\t[leftMost],\r\n\t\t\t\t\tleftMost.friendly ? gameState.gameState.player : gameState.gameState.opponent,\r\n\t\t\t\t\tleftMost.friendly ? gameState.gameState.opponent : gameState.gameState.player,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t// Putricide-only\r\n\telse if (attackingEntity.additionalCards?.includes(CardIds.IncorporealCorporal_BG26_RLK_117)) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t}\r\n\r\n\tattackingBoard\r\n\t\t.filter((e) => e.additionalCards?.includes(CardIds.FesterootHulk_BG_GIL_655))\r\n\t\t.forEach((e) => {\r\n\t\t\tmodifyStats(e, 1, 0, attackingBoard, attackingBoardHero, gameState);\r\n\t\t});\r\n\r\n\tapplyOnAttackQuest(attackingEntity, attackingBoard, attackingBoardHero, gameState);\r\n};\r\n\r\nconst applyOnAttackQuest = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst quests = attackingBoardHero.questEntities ?? [];\r\n\tfor (const quest of quests) {\r\n\t\tswitch (quest.CardId) {\r\n\t\t\tcase CardIds.CrackTheCase:\r\n\t\t\t\tonQuestProgressUpdated(attackingBoardHero, quest, attackingBoard, gameState);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tconst trinkets = attackingBoardHero.trinkets ?? [];\r\n\tfor (const trinket of trinkets) {\r\n\t\tswitch (trinket.cardId) {\r\n\t\t\tcase CardIds.JarOGems_BG30_MagicItem_546:\r\n\t\t\t\ttrinket.scriptDataNum1--;\r\n\t\t\t\tif (trinket.scriptDataNum1 <= 0) {\r\n\t\t\t\t\tfor (const entity of attackingBoard.filter((e) =>\r\n\t\t\t\t\t\thasCorrectTribe(e, attackingBoardHero, Race.QUILBOAR, gameState.allCards),\r\n\t\t\t\t\t)) {\r\n\t\t\t\t\t\tplayBloodGemsOn(trinket, entity, 1, attackingBoard, attackingBoardHero, gameState);\r\n\t\t\t\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\t\t\t\ttrinket,\r\n\t\t\t\t\t\t\tentity,\r\n\t\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttrinket.scriptDataNum1 = gameState.cardsData.defaultScriptDataNum(trinket.cardId);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"after-attack.js","sourceRoot":"","sources":["../../src/simulation/after-attack.ts"],"names":[],"mappings":"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","sourcesContent":["import { CardIds, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { updateStealth } from '../keywords/stealth';\r\nimport { grantStatsToMinionsOfEachType, hasCorrectTribe } from '../utils';\r\nimport { playBloodGemsOn } from './blood-gems';\r\nimport { addCardsInHand } from './cards-in-hand';\r\nimport { processDeathrattleForMinion } from './deathrattle-orchestration';\r\nimport { getValidDeathrattles } from './deathrattle-utils';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { onQuestProgressUpdated } from './quest';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const applyAfterAttackEffects = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tdamageDoneByAttacker: number,\r\n\tdamageDoneByDefender: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\t// https://replays.firestoneapp.com/?reviewId=9c3ba0f2-d049-4f79-8ec2-7b20ec8d0f68&turn=11&action=5\r\n\t// It looks like Stealth is removed only once the damage is dealt?\r\n\tupdateStealth(attackingEntity, false, attackingBoard, attackingBoardHero, defendingBoardHero, gameState);\r\n\r\n\tlet secretTriggered = null;\r\n\tif (\r\n\t\t(secretTriggered = defendingBoardHero.secrets?.find(\r\n\t\t\t(secret) => !secret.triggered && secret?.cardId === CardIds.Reckoning_TB_Bacon_Secrets_14,\r\n\t\t)) != null\r\n\t) {\r\n\t\t// console.log('triggering secret?', damageDoneByAttacker, stringifySimpleCard(attackingEntity, allCards));\r\n\t\tif (damageDoneByAttacker >= 3 && !(attackingEntity.health <= 0 || attackingEntity.definitelyDead)) {\r\n\t\t\tsecretTriggered.triggered = true;\r\n\t\t\tattackingEntity.definitelyDead = true;\r\n\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\tsecretTriggered,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\tif (attackingEntity.cardId === CardIds.Bonker_BG20_104 || attackingEntity.cardId === CardIds.Bonker_BG20_104_G) {\r\n\t\tconst quantity = attackingEntity.cardId === CardIds.Bonker_BG20_104_G ? 2 : 1;\r\n\t\tconst cards = quantity === 1 ? [CardIds.BloodGem] : [CardIds.BloodGem, CardIds.BloodGem];\r\n\t\taddCardsInHand(attackingBoardHero, attackingBoard, cards, gameState);\r\n\t} else if (attackingEntity.cardId === CardIds.Yrel_BG23_350 || attackingEntity.cardId === CardIds.Yrel_BG23_350_G) {\r\n\t\tconst modifier = attackingEntity.cardId === CardIds.Yrel_BG23_350_G ? 2 : 1;\r\n\t\tgrantStatsToMinionsOfEachType(\r\n\t\t\tattackingEntity,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tmodifier * 1,\r\n\t\t\tmodifier * 2,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.IncorporealCorporal_BG26_RLK_117 ||\r\n\t\tattackingEntity.cardId === CardIds.IncorporealCorporal_BG26_RLK_117_G\r\n\t) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.MonstrousMacaw_BGS_078 ||\r\n\t\tattackingEntity.cardId === CardIds.MonstrousMacaw_TB_BaconUps_135\r\n\t) {\r\n\t\tconst loops = attackingEntity.cardId === CardIds.MonstrousMacaw_TB_BaconUps_135 ? 2 : 1;\r\n\t\tconst targetBoard = attackingBoard.filter((e) => e.entityId !== attackingEntity.entityId);\r\n\t\tconst validDeathrattles = getValidDeathrattles(targetBoard, gameState);\r\n\t\tconst leftMost = validDeathrattles[0];\r\n\t\tif (!!leftMost) {\r\n\t\t\tfor (let i = 0; i < loops; i++) {\r\n\t\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\tleftMost,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t);\r\n\t\t\t\tconst indexFromRight = attackingBoard.length - (attackingBoard.indexOf(leftMost) + 1);\r\n\t\t\t\tprocessDeathrattleForMinion(\r\n\t\t\t\t\tleftMost,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\t[leftMost],\r\n\t\t\t\t\tleftMost.friendly ? gameState.gameState.player : gameState.gameState.opponent,\r\n\t\t\t\t\tleftMost.friendly ? gameState.gameState.opponent : gameState.gameState.player,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t// Putricide-only\r\n\telse if (attackingEntity.additionalCards?.includes(CardIds.IncorporealCorporal_BG26_RLK_117)) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t}\r\n\r\n\tattackingBoard\r\n\t\t.filter((e) => e.additionalCards?.includes(CardIds.FesterootHulk_BG_GIL_655))\r\n\t\t.forEach((e) => {\r\n\t\t\tmodifyStats(e, 1, 0, attackingBoard, attackingBoardHero, gameState);\r\n\t\t});\r\n\r\n\tapplyOnAttackQuest(attackingEntity, attackingBoard, attackingBoardHero, gameState);\r\n};\r\n\r\nconst applyOnAttackQuest = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst quests = attackingBoardHero.questEntities ?? [];\r\n\tfor (const quest of quests) {\r\n\t\tswitch (quest.CardId) {\r\n\t\t\tcase CardIds.CrackTheCase:\r\n\t\t\t\tonQuestProgressUpdated(attackingBoardHero, quest, attackingBoard, gameState);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tconst trinkets = attackingBoardHero.trinkets ?? [];\r\n\tfor (const trinket of trinkets) {\r\n\t\tswitch (trinket.cardId) {\r\n\t\t\tcase CardIds.JarOGems_BG30_MagicItem_546:\r\n\t\t\t\ttrinket.scriptDataNum1--;\r\n\t\t\t\tif (trinket.scriptDataNum1 <= 0) {\r\n\t\t\t\t\tfor (const entity of attackingBoard.filter((e) =>\r\n\t\t\t\t\t\thasCorrectTribe(e, attackingBoardHero, Race.QUILBOAR, gameState.allCards),\r\n\t\t\t\t\t)) {\r\n\t\t\t\t\t\tplayBloodGemsOn(trinket, entity, 1, attackingBoard, attackingBoardHero, gameState);\r\n\t\t\t\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\t\t\t\ttrinket,\r\n\t\t\t\t\t\t\tentity,\r\n\t\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttrinket.scriptDataNum1 = gameState.cardsData.defaultScriptDataNum(trinket.cardId);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n};\r\n"]}
|
|
@@ -107,7 +107,7 @@ const performAttack = (attackingEntity, defendingEntity, attackingBoard, attacki
|
|
|
107
107
|
else if (["BG22_001", "BG22_001_G"].includes(attackingEntity.cardId)) {
|
|
108
108
|
const spawns = (0, deathrattle_spawns_1.spawnEntities)(attackingEntity.cardId === "BG22_001_G"
|
|
109
109
|
? "BG22_001_G"
|
|
110
|
-
: "BG22_001t2", 1, attackingBoard, attackingBoardHero, defendingBoard, defendingBoardHero, gameState
|
|
110
|
+
: "BG22_001t2", 1, attackingBoard, attackingBoardHero, defendingBoard, defendingBoardHero, gameState, true, true);
|
|
111
111
|
if (spawns.length > 0) {
|
|
112
112
|
const sourceIndex = attackingBoard.indexOf(attackingEntity);
|
|
113
113
|
const actualSpawns = (0, spawns_1.performEntitySpawns)(spawns, attackingBoard, attackingBoardHero, attackingEntity, sourceIndex, defendingBoard, defendingBoardHero, gameState);
|
|
@@ -491,7 +491,7 @@ const handleAfterMinionsDeathsForBoard = (friendlyBoard, friendlyDeadEntities, f
|
|
|
491
491
|
secretTriggered.triggered = true;
|
|
492
492
|
for (let i = 0; i < 2; i++) {
|
|
493
493
|
const toSummon = (0, utils_1.pickRandom)(gameState.cardsData.demonSpawns);
|
|
494
|
-
candidateEntities.push(...(0, deathrattle_spawns_1.spawnEntities)(toSummon, 1, friendlyBoard, friendlyHeroEntity, otherBoard, otherHeroEntity, gameState
|
|
494
|
+
candidateEntities.push(...(0, deathrattle_spawns_1.spawnEntities)(toSummon, 1, friendlyBoard, friendlyHeroEntity, otherBoard, otherHeroEntity, gameState, friendlyHeroEntity.friendly, false));
|
|
495
495
|
}
|
|
496
496
|
}
|
|
497
497
|
}
|
|
@@ -1 +1 @@
|
|
|
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, CardIds, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { 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 { groupByFunction, pickRandom } from '../services/utils';\r\nimport { addImpliedMechanics, hasCorrectTribe, isFish } from '../utils';\r\nimport { applyAfterAttackEffects } from './after-attack';\r\nimport { onEntityDamaged } from './damage-effects';\r\nimport { applyMonstrosity, rememberDeathrattles } from './deathrattle-effects';\r\nimport { orchestrateMinionDeathEffects } from './deathrattle-orchestration';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { applyFrenzy } from './frenzy';\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 { 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): void => {\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}\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 = 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) {\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);\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};\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) => {\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\tapplyAfterAttackEffects(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\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\tisAttackingImmediately,\r\n\t);\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tattackingEntity.immuneWhenAttackCharges = Math.max(0, (attackingEntity.immuneWhenAttackCharges ?? 0) - 1);\r\n\tif (\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\r\n\tif (hasCorrectTribe(attackingEntity, attackingBoardHero, Race.DRAGON, gameState.allCards)) {\r\n\t\tconst prestors = attackingBoard\r\n\t\t\t.filter((e) => e.entityId !== attackingEntity.entityId)\r\n\t\t\t.filter(\r\n\t\t\t\t(e) =>\r\n\t\t\t\t\te.cardId === CardIds.PrestorsPyrospawn_BG21_012 ||\r\n\t\t\t\t\te.cardId === CardIds.PrestorsPyrospawn_BG21_012_G,\r\n\t\t\t);\r\n\t\tprestors.forEach((prestor) => {\r\n\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\tprestor,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dealDamageToMinion(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tprestor,\r\n\t\t\t\tprestor.cardId === CardIds.PrestorsPyrospawn_BG21_012_G ? 6 : 3,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t});\r\n\t}\r\n\tif (\r\n\t\tattackingEntity.cardId === CardIds.Atramedes_BG23_362 ||\r\n\t\tattackingEntity.cardId === CardIds.Atramedes_BG23_362_G\r\n\t) {\r\n\t\tconst targets = [defendingEntity, ...getNeighbours(defendingBoard, defendingEntity)];\r\n\t\tconst multiplier = attackingEntity.cardId === CardIds.Atramedes_BG23_362_G ? 2 : 1;\r\n\r\n\t\tfor (let i = 0; i < multiplier; i++) {\r\n\t\t\ttargets.forEach((target) => {\r\n\t\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t);\r\n\t\t\t\tdamageDoneByAttacker += dealDamageToMinion(\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\t3,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\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} else if ([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.allCards,\r\n\t\t\tgameState.cardsData,\r\n\t\t\tgameState.sharedState,\r\n\t\t\tgameState.spectator,\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\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\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\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\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);\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\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\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)) {\r\n\t\tattackingBoard.forEach((e) => (e.hasAttacked = 0));\r\n\t} else {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => !entity.hasAttacked);\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): 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.map((e) => e.entityId).indexOf(entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\tneighbours.push(board[index - 1]);\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}\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.map((e) => e.entityId).indexOf(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,\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\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\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t}\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(target, board, hero, otherBoard, otherHero, actualDamageDone, gameState);\r\n\t}\r\n\tif (!isDeadBeforeDamage && actualDamageDone > 0) {\r\n\t\ttarget.lastAffectedByEntity = damageSource;\r\n\r\n\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\tonMinionKill(damageSource, target, otherBoard, otherHero, board, hero, [], gameState);\r\n\t\t}\r\n\t}\r\n\tconst defendingEntityIndex = board.map((entity) => entity.entityId).indexOf(target.entityId);\r\n\tboard[defendingEntityIndex] = target;\r\n\treturn actualDamageDone;\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\tif (attackingEntity.entityId === forcedFaceOff.attacker.entityId) {\r\n\t\t\t\t\tlet def = null;\r\n\t\t\t\t\tif (!!(def = defendingBoard.find((e) => debugState.isCorrectEntity(forcedFaceOff.defender, e)))) {\r\n\t\t\t\t\t\t// Remove the face-off\r\n\t\t\t\t\t\tdebugState.forcedFaceOff = debugState.forcedFaceOff.filter((f) => f != forcedFaceOff);\r\n\t\t\t\t\t\treturn def;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t}\r\n\t}\r\n\t// if (attackingEntity.entityId === 4946) {\r\n\t// \tlet def = null;\r\n\t// \tif (!!(def = defendingBoard.find((e) => e.entityId === 7170))) {\r\n\t// \t\treturn def;\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) {\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\tlet chosenDefender = pickRandom(possibleDefenders);\r\n\tif (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): 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(newTarget, otherBoard, otherHero, entityBoard, entityBoardHero, damageDone, gameState);\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\tif (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 && 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\tif (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\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\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\tboard1\r\n\t\t.filter(\r\n\t\t\t(entity) =>\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy ||\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy_G,\r\n\t\t)\r\n\t\t.forEach((entity) => applyMonstrosity(entity, deadEntities1, board1, board1Hero, gameState));\r\n\tboard2\r\n\t\t.filter(\r\n\t\t\t(entity) =>\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy ||\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy_G,\r\n\t\t)\r\n\t\t.forEach((entity) => applyMonstrosity(entity, deadEntities2, board2, board2Hero, gameState));\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(board1, deadEntities1, board1Hero, board2, deadEntities2, board2Hero, gameState);\r\n};\r\n\r\nconst handleAfterMinionsDeaths = (\r\n\tboard1: BoardEntity[],\r\n\tdeadEntities1: BoardEntity[],\r\n\theroEntity1: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tdeadEntities2: BoardEntity[],\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 ? heroEntity1 : heroEntity2,\r\n\t\trandom ? board2 : board1,\r\n\t\trandom ? deadEntities2 : deadEntities1,\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 ? heroEntity1 : heroEntity2,\r\n\t\t!random ? board2 : board1,\r\n\t\t!random ? deadEntities2 : deadEntities1,\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\tfriendlyHeroEntity: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherDeadEntities: BoardEntity[],\r\n\totherHeroEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities = [];\r\n\tlet secretTriggered = null;\r\n\tif (\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.allCards,\r\n\t\t\t\t\t\tgameState.cardsData,\r\n\t\t\t\t\t\tgameState.sharedState,\r\n\t\t\t\t\t\tgameState.spectator,\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: readonly BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnMinionKilledInput {\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, CardIds, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { 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 { groupByFunction, pickRandom } from '../services/utils';\r\nimport { addImpliedMechanics, hasCorrectTribe, isFish } from '../utils';\r\nimport { applyAfterAttackEffects } from './after-attack';\r\nimport { onEntityDamaged } from './damage-effects';\r\nimport { applyMonstrosity, rememberDeathrattles } from './deathrattle-effects';\r\nimport { orchestrateMinionDeathEffects } from './deathrattle-orchestration';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { applyFrenzy } from './frenzy';\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 { 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): void => {\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}\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 = 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) {\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);\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};\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) => {\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\tapplyAfterAttackEffects(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\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\tisAttackingImmediately,\r\n\t);\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tattackingEntity.immuneWhenAttackCharges = Math.max(0, (attackingEntity.immuneWhenAttackCharges ?? 0) - 1);\r\n\tif (\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\r\n\tif (hasCorrectTribe(attackingEntity, attackingBoardHero, Race.DRAGON, gameState.allCards)) {\r\n\t\tconst prestors = attackingBoard\r\n\t\t\t.filter((e) => e.entityId !== attackingEntity.entityId)\r\n\t\t\t.filter(\r\n\t\t\t\t(e) =>\r\n\t\t\t\t\te.cardId === CardIds.PrestorsPyrospawn_BG21_012 ||\r\n\t\t\t\t\te.cardId === CardIds.PrestorsPyrospawn_BG21_012_G,\r\n\t\t\t);\r\n\t\tprestors.forEach((prestor) => {\r\n\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\tprestor,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dealDamageToMinion(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tprestor,\r\n\t\t\t\tprestor.cardId === CardIds.PrestorsPyrospawn_BG21_012_G ? 6 : 3,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t});\r\n\t}\r\n\tif (\r\n\t\tattackingEntity.cardId === CardIds.Atramedes_BG23_362 ||\r\n\t\tattackingEntity.cardId === CardIds.Atramedes_BG23_362_G\r\n\t) {\r\n\t\tconst targets = [defendingEntity, ...getNeighbours(defendingBoard, defendingEntity)];\r\n\t\tconst multiplier = attackingEntity.cardId === CardIds.Atramedes_BG23_362_G ? 2 : 1;\r\n\r\n\t\tfor (let i = 0; i < multiplier; i++) {\r\n\t\t\ttargets.forEach((target) => {\r\n\t\t\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t);\r\n\t\t\t\tdamageDoneByAttacker += dealDamageToMinion(\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\t3,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\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} else if ([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\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\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\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\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);\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\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\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)) {\r\n\t\tattackingBoard.forEach((e) => (e.hasAttacked = 0));\r\n\t} else {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => !entity.hasAttacked);\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): 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.map((e) => e.entityId).indexOf(entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\tneighbours.push(board[index - 1]);\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}\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.map((e) => e.entityId).indexOf(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,\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\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\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t}\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(target, board, hero, otherBoard, otherHero, actualDamageDone, gameState);\r\n\t}\r\n\tif (!isDeadBeforeDamage && actualDamageDone > 0) {\r\n\t\ttarget.lastAffectedByEntity = damageSource;\r\n\r\n\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\tonMinionKill(damageSource, target, otherBoard, otherHero, board, hero, [], gameState);\r\n\t\t}\r\n\t}\r\n\tconst defendingEntityIndex = board.map((entity) => entity.entityId).indexOf(target.entityId);\r\n\tboard[defendingEntityIndex] = target;\r\n\treturn actualDamageDone;\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\tif (attackingEntity.entityId === forcedFaceOff.attacker.entityId) {\r\n\t\t\t\t\tlet def = null;\r\n\t\t\t\t\tif (!!(def = defendingBoard.find((e) => debugState.isCorrectEntity(forcedFaceOff.defender, e)))) {\r\n\t\t\t\t\t\t// Remove the face-off\r\n\t\t\t\t\t\tdebugState.forcedFaceOff = debugState.forcedFaceOff.filter((f) => f != forcedFaceOff);\r\n\t\t\t\t\t\treturn def;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t}\r\n\t}\r\n\t// if (attackingEntity.entityId === 4946) {\r\n\t// \tlet def = null;\r\n\t// \tif (!!(def = defendingBoard.find((e) => e.entityId === 7170))) {\r\n\t// \t\treturn def;\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) {\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\tlet chosenDefender = pickRandom(possibleDefenders);\r\n\tif (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): 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(newTarget, otherBoard, otherHero, entityBoard, entityBoardHero, damageDone, gameState);\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\tif (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 && 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\tif (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\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\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\tboard1\r\n\t\t.filter(\r\n\t\t\t(entity) =>\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy ||\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy_G,\r\n\t\t)\r\n\t\t.forEach((entity) => applyMonstrosity(entity, deadEntities1, board1, board1Hero, gameState));\r\n\tboard2\r\n\t\t.filter(\r\n\t\t\t(entity) =>\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy ||\r\n\t\t\t\tentity.cardId === CardIds.Monstrosity_BG20_HERO_282_Buddy_G,\r\n\t\t)\r\n\t\t.forEach((entity) => applyMonstrosity(entity, deadEntities2, board2, board2Hero, gameState));\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(board1, deadEntities1, board1Hero, board2, deadEntities2, board2Hero, gameState);\r\n};\r\n\r\nconst handleAfterMinionsDeaths = (\r\n\tboard1: BoardEntity[],\r\n\tdeadEntities1: BoardEntity[],\r\n\theroEntity1: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tdeadEntities2: BoardEntity[],\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 ? heroEntity1 : heroEntity2,\r\n\t\trandom ? board2 : board1,\r\n\t\trandom ? deadEntities2 : deadEntities1,\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 ? heroEntity1 : heroEntity2,\r\n\t\t!random ? board2 : board1,\r\n\t\t!random ? deadEntities2 : deadEntities1,\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\tfriendlyHeroEntity: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherDeadEntities: BoardEntity[],\r\n\totherHeroEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities = [];\r\n\tlet secretTriggered = null;\r\n\tif (\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: readonly BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnMinionKilledInput {\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"]}
|
|
@@ -308,7 +308,7 @@ const handleAvenge = (boardWithDeadEntity, boardWithDeadEntityHero, deadEntity,
|
|
|
308
308
|
break;
|
|
309
309
|
case "BG30_MagicItem_713":
|
|
310
310
|
const randomUndead = gameState.cardsData.getRandomMinionForTribe(reference_data_1.Race.UNDEAD, boardWithDeadEntityHero.tavernTier);
|
|
311
|
-
candidatesEntitiesSpawnedFromAvenge.push(...(0, deathrattle_spawns_1.spawnEntities)(randomUndead, 1, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState
|
|
311
|
+
candidatesEntitiesSpawnedFromAvenge.push(...(0, deathrattle_spawns_1.spawnEntities)(randomUndead, 1, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState, deadEntity.friendly, false, false, false));
|
|
312
312
|
(0, cards_in_hand_1.addCardsInHand)(boardWithDeadEntityHero, boardWithDeadEntity, [randomUndead], gameState);
|
|
313
313
|
break;
|
|
314
314
|
}
|
|
@@ -318,7 +318,7 @@ const handleAvenge = (boardWithDeadEntity, boardWithDeadEntityHero, deadEntity,
|
|
|
318
318
|
const handleHeroAvenge = (deadEntity, heroPower, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, candidatesEntitiesSpawnedFromAvenge, gameState) => {
|
|
319
319
|
switch (heroPower.cardId) {
|
|
320
320
|
case "BG22_HERO_305p":
|
|
321
|
-
candidatesEntitiesSpawnedFromAvenge.push(...(0, deathrattle_spawns_1.spawnEntities)("BG22_HERO_305t", 1, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState
|
|
321
|
+
candidatesEntitiesSpawnedFromAvenge.push(...(0, deathrattle_spawns_1.spawnEntities)("BG22_HERO_305t", 1, boardWithDeadEntity, boardWithDeadEntityHero, otherBoard, otherBoardHero, gameState, deadEntity.friendly, false, false, false));
|
|
322
322
|
break;
|
|
323
323
|
case "BG22_HERO_003p":
|
|
324
324
|
boardWithDeadEntity
|