@firestone-hs/simulate-bgs-battle 1.1.351 → 1.1.352

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.
@@ -9,6 +9,7 @@ export interface BgsPlayerEntity {
9
9
  readonly heroPowerUsed: boolean;
10
10
  readonly heroPowerInfo?: number;
11
11
  readonly heroPowerInfo2?: number;
12
+ friendly?: boolean;
12
13
  entityId?: number;
13
14
  questRewards?: readonly string[];
14
15
  questRewardEntities?: readonly {
@@ -1 +1 @@
1
- {"version":3,"file":"bgs-player-entity.js","sourceRoot":"","sources":["../src/bgs-player-entity.ts"],"names":[],"mappings":"","sourcesContent":["import { BoardEntity } from './board-entity';\r\nimport { BoardSecret } from './board-secret';\r\n\r\nexport interface BgsPlayerEntity {\r\n\treadonly cardId: string;\r\n\treadonly nonGhostCardId?: string;\r\n\treadonly hpLeft: number;\r\n\treadonly tavernTier: number;\r\n\treadonly heroPowerId?: string | undefined | null;\r\n\treadonly heroPowerUsed: boolean;\r\n\treadonly heroPowerInfo?: number;\r\n\treadonly heroPowerInfo2?: number;\r\n\tentityId?: number;\r\n\tquestRewards?: readonly string[];\r\n\tquestRewardEntities?: readonly {\r\n\t\tcardId: string;\r\n\t\tavengeDefault?: number;\r\n\t\tavengeCurrent?: number;\r\n\t}[];\r\n\thand?: BoardEntity[];\r\n\tsecrets?: BoardSecret[];\r\n\tavengeCurrent?: number;\r\n\tavengeDefault?: number;\r\n\tglobalInfo?: BgsPlayerGlobalInfo;\r\n\r\n\tdeadEyeDamageDone?: number;\r\n\trapidReanimationMinion?: BoardEntity;\r\n\trapidReanimationIndexFromRight?: number;\r\n}\r\n\r\nexport interface BgsPlayerGlobalInfo {\r\n\tEternalKnightsDeadThisGame?: number;\r\n\tUndeadAttackBonus?: number;\r\n\tChoralAttackBuff?: number;\r\n\tChoralHealthBuff?: number;\r\n\tFrostlingBonus?: number;\r\n\tBloodGemAttackBonus?: number;\r\n\tBloodGemHealthBonus?: number;\r\n\tGoldrinnBuffAtk?: number;\r\n\tGoldrinnBuffHealth?: number;\r\n\tTavernSpellsCastThisGame?: number;\r\n}\r\n"]}
1
+ {"version":3,"file":"bgs-player-entity.js","sourceRoot":"","sources":["../src/bgs-player-entity.ts"],"names":[],"mappings":"","sourcesContent":["import { BoardEntity } from './board-entity';\r\nimport { BoardSecret } from './board-secret';\r\n\r\nexport interface BgsPlayerEntity {\r\n\treadonly cardId: string;\r\n\treadonly nonGhostCardId?: string;\r\n\treadonly hpLeft: number;\r\n\treadonly tavernTier: number;\r\n\treadonly heroPowerId?: string | undefined | null;\r\n\treadonly heroPowerUsed: boolean;\r\n\treadonly heroPowerInfo?: number;\r\n\treadonly heroPowerInfo2?: number;\r\n\tfriendly?: boolean;\r\n\tentityId?: number;\r\n\tquestRewards?: readonly string[];\r\n\tquestRewardEntities?: readonly {\r\n\t\tcardId: string;\r\n\t\tavengeDefault?: number;\r\n\t\tavengeCurrent?: number;\r\n\t}[];\r\n\thand?: BoardEntity[];\r\n\tsecrets?: BoardSecret[];\r\n\tavengeCurrent?: number;\r\n\tavengeDefault?: number;\r\n\tglobalInfo?: BgsPlayerGlobalInfo;\r\n\r\n\tdeadEyeDamageDone?: number;\r\n\trapidReanimationMinion?: BoardEntity;\r\n\trapidReanimationIndexFromRight?: number;\r\n}\r\n\r\nexport interface BgsPlayerGlobalInfo {\r\n\tEternalKnightsDeadThisGame?: number;\r\n\tUndeadAttackBonus?: number;\r\n\tChoralAttackBuff?: number;\r\n\tChoralHealthBuff?: number;\r\n\tFrostlingBonus?: number;\r\n\tBloodGemAttackBonus?: number;\r\n\tBloodGemHealthBonus?: number;\r\n\tGoldrinnBuffAtk?: number;\r\n\tGoldrinnBuffHealth?: number;\r\n\tTavernSpellsCastThisGame?: number;\r\n}\r\n"]}
@@ -52,6 +52,7 @@ const simulateBattle = (battleInput, cards, cardsData) => {
52
52
  locked: cardsData.getTavernLevel(entity.cardId) > playerInfo.player.tavernTier,
53
53
  }));
54
54
  playerInfo.player.secrets = (_d = playerInfo.secrets) === null || _d === void 0 ? void 0 : _d.filter((e) => !!(e === null || e === void 0 ? void 0 : e.cardId));
55
+ playerInfo.player.friendly = true;
55
56
  const opponentBoard = opponentInfo.board.map((entity) => ({
56
57
  ...(0, utils_1.addImpliedMechanics)(entity, cardsData),
57
58
  friendly: false,
@@ -59,6 +60,7 @@ const simulateBattle = (battleInput, cards, cardsData) => {
59
60
  }));
60
61
  const opponentHand = (_e = opponentInfo.player.hand) === null || _e === void 0 ? void 0 : _e.map((entity) => ({ ...(0, utils_1.addImpliedMechanics)(entity, cardsData), friendly: true }));
61
62
  opponentInfo.player.secrets = (_f = opponentInfo.secrets) === null || _f === void 0 ? void 0 : _f.filter((e) => !!(e === null || e === void 0 ? void 0 : e.cardId));
63
+ opponentInfo.player.friendly = true;
62
64
  (0, auras_1.setMissingAuras)(playerBoard, playerInfo.player, opponentInfo.player, cards);
63
65
  (0, auras_1.setMissingAuras)(opponentBoard, opponentInfo.player, playerInfo.player, cards);
64
66
  (0, auras_1.setImplicitDataHero)(playerInfo.player, cardsData, true);
@@ -1 +1 @@
1
- {"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":";;;AACA,iEAAwE;AAGxE,mDAA+C;AAE/C,8CAA0E;AAC1E,sDAAmD;AACnD,gEAA6D;AAC7D,mCAA8C;AAE9C,MAAM,KAAK,GAAG,IAAI,gCAAe,EAAE,CAAC;AAKpC,kBAAe,KAAK,EAAE,KAAK,EAAgB,EAAE;;IAC5C,MAAM,WAAW,GAAkB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9C,SAAS,CAAC,YAAY,CACrB,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,WAAW,mCAAI,MAAA,WAAW,CAAC,OAAO,0CAAE,WAAW,EACtE,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,SAAS,mCAAI,EAAE,CACtC,CAAC;IACF,MAAM,gBAAgB,GAAG,IAAA,sBAAc,EAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAEvE,MAAM,QAAQ,GAAG;QAChB,UAAU,EAAE,GAAG;QACf,eAAe,EAAE,KAAK;QACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;KACtC,CAAC;IACF,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEK,MAAM,cAAc,GAAG,CAC7B,WAA0B,EAC1B,KAAsB,EACtB,SAAoB,EACD,EAAE;;IACrB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,MAAM,qBAAqB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,qBAAqB,KAAI,IAAI,CAAC;IACjF,MAAM,mBAAmB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,mBAAmB,KAAI,IAAI,CAAC;IAE7E,MAAM,gBAAgB,GAAqB;QAC1C,SAAS,EAAE,CAAC;QACZ,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,IAAI,EAAE,CAAC;QACP,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,gBAAgB,EAAE,SAAS;QAC3B,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,SAAS;QACtB,iBAAiB,EAAE,SAAS;QAC5B,gBAAgB,EAAE,SAAS;QAC3B,iBAAiB,EAAE,SAAS;KAC5B,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC;IAC3C,MAAM,YAAY,GAAG,WAAW,CAAC,aAAa,CAAC;IAE/C,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CACvC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAkB,CAAA,CAC1F,CAAC;IACF,MAAM,UAAU,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,IAAI,0CAAE,GAAG,CAC7C,CAAC,MAAM,EAAE,EAAE,CACV,CAAC;QACA,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC;QACzC,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU;KAC9D,CAAA,CAClB,CAAC;IACF,UAAU,CAAC,MAAM,CAAC,OAAO,GAAG,MAAA,UAAU,CAAC,OAAO,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAC3C,CAAC,MAAM,EAAE,EAAE,CACV,CAAC;QACA,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC;QACzC,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU;KAC9D,CAAA,CAClB,CAAC;IACF,MAAM,YAAY,GAAG,MAAA,YAAY,CAAC,MAAM,CAAC,IAAI,0CAAE,GAAG,CACjD,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAkB,CAAA,CAC1F,CAAC;IACF,YAAY,CAAC,MAAM,CAAC,OAAO,GAAG,MAAA,YAAY,CAAC,OAAO,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,CAAC;IAG/E,IAAA,uBAAe,EAAC,WAAW,EAAE,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5E,IAAA,uBAAe,EAAC,aAAa,EAAE,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAK9E,IAAA,2BAAmB,EAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACxD,IAAA,2BAAmB,EAAC,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAI3D,MAAM,UAAU,GAAkB;QACjC,WAAW,EAAE;YACZ,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE;gBACP,GAAG,UAAU,CAAC,MAAM;gBACpB,IAAI,EAAE,UAAU;aAChB;SACD;QACD,aAAa,EAAE;YACd,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE;gBACP,GAAG,YAAY,CAAC,MAAM;gBACtB,IAAI,EAAE,YAAY;aAClB;SACD;QACD,SAAS,EAAE,WAAW,CAAC,SAAS;KACf,CAAC;IACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,qBAAS,CAC9B,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EACrC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAC1C,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EACvC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAC5C,CAAC;IACF,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClD,MAAM,KAAK,GAAkB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,SAAS,CAAC,oBAAoB,CAClD,KAAK,CAAC,WAAW,CAAC,KAAK,EACvB,KAAK,CAAC,WAAW,CAAC,MAAM,EACxB,KAAK,CAAC,aAAa,CAAC,KAAK,EACzB,KAAK,CAAC,aAAa,CAAC,MAAM,EAC1B,KAAK,CAAC,SAAS,EACf,SAAS,CACT,CAAC;QACF,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,qBAAqB,EAAE;YAE/C,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YACxG,MAAM;SACN;QACD,IAAI,CAAC,YAAY,EAAE;YAClB,SAAS;SACT;QACD,IAAI,YAAY,CAAC,MAAM,KAAK,KAAK,EAAE;YAClC,gBAAgB,CAAC,GAAG,EAAE,CAAC;YACvB,gBAAgB,CAAC,SAAS,IAAI,YAAY,CAAC,WAAW,CAAC;YACvD,IAAI,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE;gBACxE,gBAAgB,CAAC,SAAS,EAAE,CAAC;aAC7B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;YACxB,gBAAgB,CAAC,UAAU,IAAI,YAAY,CAAC,WAAW,CAAC;YACxD,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAA,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnF,IACC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;gBACrC,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAChE;gBACD,gBAAgB,CAAC,UAAU,EAAE,CAAC;aAC9B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;SACxB;QACD,SAAS,CAAC,kBAAkB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;KAClD;IACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;IAC1F,gBAAgB,CAAC,UAAU,GAAG,aAAa,CAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACnE,gBAAgB,CAAC,GAAG,EACpB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,gBAAgB,GAAG,aAAa,CAChD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACzE,gBAAgB,CAAC,SAAS,EAC1B,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACpE,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,iBAAiB,GAAG,aAAa,CACjD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EAC1E,gBAAgB,CAAC,UAAU,EAC3B,YAAY,CACZ,CAAC;IAEF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,GAAG,GAAG,gBAAgB,CAAC,WAAW,GAAG,gBAAgB,CAAC,UAAU,EAChE,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IAEF,gBAAgB,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC;IAC9G,gBAAgB,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC;IAChH,gBAAgB,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjH,gBAAgB,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,IAAI;QACzD,CAAC,CAAC,gBAAgB,CAAC,UAAU,GAAG,gBAAgB,CAAC,IAAI;QACrD,CAAC,CAAC,CAAC,CAAC;IACL,IAAI,gBAAgB,CAAC,gBAAgB,GAAG,CAAC,IAAI,gBAAgB,CAAC,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE;QAC9G,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;KACvE;IACD,IAAI,gBAAgB,CAAC,iBAAiB,GAAG,CAAC,IAAI,gBAAgB,CAAC,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE;QAClH,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAC;KAC1E;IACD,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpE,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,gBAAgB,CAAC,cAAc,GAAG,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAClE,OAAO,gBAAgB,CAAC;AACzB,CAAC,CAAC;AAjLW,QAAA,cAAc,kBAiLzB;AAEF,MAAM,aAAa,GAAG,CAAC,YAAoB,EAAE,YAAoB,EAAE,UAAkB,EAAU,EAAE;IAChG,IAAI,YAAY,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC,EAAE;QAC7C,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,YAAY,KAAK,GAAG,IAAI,YAAY,KAAK,UAAU,EAAE;QACxD,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAA0B,EAAE;IACnF,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7B,GAAG,MAAM;QACT,YAAY,EAAE,0BAA0B,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC;KACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEW,QAAA,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;CAoBhC,CAAC;AAEF,MAAM,0BAA0B,GAAG,CAClC,YAA2E,EAC3E,SAA4B,EACoC,EAAE;IAClE,OAAO,YAAY,CAAC,MAAM,CACzB,CAAC,OAAO,EAAE,EAAE,CACX,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAChD,yBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,MAAiB,CAAC,KAAK,CAAC,CAAC,CAC5D,CAAC;AACH,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, CardIds } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nconst cards = new AllCardsService();\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst simulationResult = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): SimulationResult => {\r\n\tconst start = Date.now();\r\n\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 5000;\r\n\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWon: 0,\r\n\t\tdamageLost: 0,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst playerInfo = battleInput.playerBoard;\r\n\tconst opponentInfo = battleInput.opponentBoard;\r\n\r\n\tconst playerBoard = playerInfo.board.map(\r\n\t\t(entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: true } as BoardEntity),\r\n\t);\r\n\tconst playerHand = playerInfo.player.hand?.map(\r\n\t\t(entity) =>\r\n\t\t\t({\r\n\t\t\t\t...addImpliedMechanics(entity, cardsData),\r\n\t\t\t\tfriendly: true,\r\n\t\t\t\tlocked: cardsData.getTavernLevel(entity.cardId) > playerInfo.player.tavernTier,\r\n\t\t\t} as BoardEntity),\r\n\t);\r\n\tplayerInfo.player.secrets = playerInfo.secrets?.filter((e) => !!e?.cardId);\r\n\tconst opponentBoard = opponentInfo.board.map(\r\n\t\t(entity) =>\r\n\t\t\t({\r\n\t\t\t\t...addImpliedMechanics(entity, cardsData),\r\n\t\t\t\tfriendly: false,\r\n\t\t\t\tlocked: cardsData.getTavernLevel(entity.cardId) > playerInfo.player.tavernTier,\r\n\t\t\t} as BoardEntity),\r\n\t);\r\n\tconst opponentHand = opponentInfo.player.hand?.map(\r\n\t\t(entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: true } as BoardEntity),\r\n\t);\r\n\topponentInfo.player.secrets = opponentInfo.secrets?.filter((e) => !!e?.cardId);\r\n\r\n\t// When using the simulator, the aura is not applied when receiving the board state. When\r\n\tsetMissingAuras(playerBoard, playerInfo.player, opponentInfo.player, cards);\r\n\tsetMissingAuras(opponentBoard, opponentInfo.player, playerInfo.player, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, cardsData, true);\r\n\tsetImplicitDataHero(opponentInfo.player, cardsData, false);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerInfo.player,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentInfo.player,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tgameState: battleInput.gameState,\r\n\t} as BgsBattleInfo;\r\n\tconst inputStr = JSON.stringify(inputReady);\r\n\tconst spectator = new Spectator(\r\n\t\tbattleInput.playerBoard.player.cardId,\r\n\t\tbattleInput.playerBoard.player.heroPowerId,\r\n\t\tbattleInput.opponentBoard.player.cardId,\r\n\t\tbattleInput.opponentBoard.player.heroPowerId,\r\n\t);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst simulator = new Simulator(cards, cardsData);\r\n\t\tconst input: BgsBattleInfo = JSON.parse(inputStr);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(\r\n\t\t\tinput.playerBoard.board,\r\n\t\t\tinput.playerBoard.player,\r\n\t\t\tinput.opponentBoard.board,\r\n\t\t\tinput.opponentBoard.player,\r\n\t\t\tinput.gameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tif (Date.now() - start > maxAcceptableDuration) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms', battleResult);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\t}\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\t// simulationResult.tiedPercent = checkRounding(Math.round((10 * (100 * simulationResult.tied)) / totalMatches) / 10, simulationResult.tied, totalMatches);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\t100 - simulationResult.lostPercent - simulationResult.wonPercent,\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\tsimulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\tsimulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? simulationResult.damageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost\r\n\t\t? simulationResult.damageLost / simulationResult.lost\r\n\t\t: 0;\r\n\tif (simulationResult.averageDamageWon > 0 && simulationResult.averageDamageWon < playerInfo.player.tavernTier) {\r\n\t\tconsole.warn('average damage won issue', simulationResult, playerInfo);\r\n\t}\r\n\tif (simulationResult.averageDamageLost > 0 && simulationResult.averageDamageLost < opponentInfo.player.tavernTier) {\r\n\t\tconsole.warn('average damage lost issue', simulationResult, opponentInfo);\r\n\t}\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples();\r\n\treturn simulationResult;\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\nconst cleanEnchantments = (board: readonly BoardEntity[]): readonly BoardEntity[] => {\r\n\tconst entityIds = board.map((entity) => entity.entityId);\r\n\treturn board.map((entity) => ({\r\n\t\t...entity,\r\n\t\tenchantments: cleanEnchantmentsForEntity(entity.enchantments, entityIds),\r\n\t}));\r\n};\r\n\r\nexport const validEnchantments = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\t// CardIds.FireInvocation_ElementFireEnchantment, // Attack is doubled, probably no use to keep it\r\n\t// CardIds.WaterInvocation_ElementWaterEnchantment, // +3 health and taunt, same\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n];\r\n\r\nconst cleanEnchantmentsForEntity = (\r\n\tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n\tentityIds: readonly number[],\r\n): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n\treturn enchantments.filter(\r\n\t\t(enchant) =>\r\n\t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n\t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n\t);\r\n};\r\n"]}
1
+ {"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":";;;AACA,iEAAwE;AAGxE,mDAA+C;AAE/C,8CAA0E;AAC1E,sDAAmD;AACnD,gEAA6D;AAC7D,mCAA8C;AAE9C,MAAM,KAAK,GAAG,IAAI,gCAAe,EAAE,CAAC;AAKpC,kBAAe,KAAK,EAAE,KAAK,EAAgB,EAAE;;IAC5C,MAAM,WAAW,GAAkB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,sBAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9C,SAAS,CAAC,YAAY,CACrB,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,WAAW,mCAAI,MAAA,WAAW,CAAC,OAAO,0CAAE,WAAW,EACtE,MAAA,MAAA,WAAW,CAAC,SAAS,0CAAE,SAAS,mCAAI,EAAE,CACtC,CAAC;IACF,MAAM,gBAAgB,GAAG,IAAA,sBAAc,EAAC,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAEvE,MAAM,QAAQ,GAAG;QAChB,UAAU,EAAE,GAAG;QACf,eAAe,EAAE,KAAK;QACtB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;KACtC,CAAC;IACF,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEK,MAAM,cAAc,GAAG,CAC7B,WAA0B,EAC1B,KAAsB,EACtB,SAAoB,EACD,EAAE;;IACrB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,MAAM,qBAAqB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,qBAAqB,KAAI,IAAI,CAAC;IACjF,MAAM,mBAAmB,GAAG,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,mBAAmB,KAAI,IAAI,CAAC;IAE7E,MAAM,gBAAgB,GAAqB;QAC1C,SAAS,EAAE,CAAC;QACZ,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,IAAI,EAAE,CAAC;QACP,UAAU,EAAE,CAAC;QACb,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,gBAAgB,EAAE,SAAS;QAC3B,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,SAAS;QACtB,iBAAiB,EAAE,SAAS;QAC5B,gBAAgB,EAAE,SAAS;QAC3B,iBAAiB,EAAE,SAAS;KAC5B,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC;IAC3C,MAAM,YAAY,GAAG,WAAW,CAAC,aAAa,CAAC;IAE/C,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CACvC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAkB,CAAA,CAC1F,CAAC;IACF,MAAM,UAAU,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,IAAI,0CAAE,GAAG,CAC7C,CAAC,MAAM,EAAE,EAAE,CACV,CAAC;QACA,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC;QACzC,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU;KAC9D,CAAA,CAClB,CAAC;IACF,UAAU,CAAC,MAAM,CAAC,OAAO,GAAG,MAAA,UAAU,CAAC,OAAO,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,CAAC;IAC3E,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;IAClC,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAC3C,CAAC,MAAM,EAAE,EAAE,CACV,CAAC;QACA,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC;QACzC,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU;KAC9D,CAAA,CAClB,CAAC;IACF,MAAM,YAAY,GAAG,MAAA,YAAY,CAAC,MAAM,CAAC,IAAI,0CAAE,GAAG,CACjD,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAkB,CAAA,CAC1F,CAAC;IACF,YAAY,CAAC,MAAM,CAAC,OAAO,GAAG,MAAA,YAAY,CAAC,OAAO,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,CAAC;IAC/E,YAAY,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;IAGpC,IAAA,uBAAe,EAAC,WAAW,EAAE,UAAU,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5E,IAAA,uBAAe,EAAC,aAAa,EAAE,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAK9E,IAAA,2BAAmB,EAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACxD,IAAA,2BAAmB,EAAC,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAI3D,MAAM,UAAU,GAAkB;QACjC,WAAW,EAAE;YACZ,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE;gBACP,GAAG,UAAU,CAAC,MAAM;gBACpB,IAAI,EAAE,UAAU;aAChB;SACD;QACD,aAAa,EAAE;YACd,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE;gBACP,GAAG,YAAY,CAAC,MAAM;gBACtB,IAAI,EAAE,YAAY;aAClB;SACD;QACD,SAAS,EAAE,WAAW,CAAC,SAAS;KACf,CAAC;IACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,qBAAS,CAC9B,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EACrC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAC1C,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EACvC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAC5C,CAAC;IACF,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,mBAAmB,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,SAAS,GAAG,IAAI,qBAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAClD,MAAM,KAAK,GAAkB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,SAAS,CAAC,oBAAoB,CAClD,KAAK,CAAC,WAAW,CAAC,KAAK,EACvB,KAAK,CAAC,WAAW,CAAC,MAAM,EACxB,KAAK,CAAC,aAAa,CAAC,KAAK,EACzB,KAAK,CAAC,aAAa,CAAC,MAAM,EAC1B,KAAK,CAAC,SAAS,EACf,SAAS,CACT,CAAC;QACF,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,qBAAqB,EAAE;YAE/C,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YACxG,MAAM;SACN;QACD,IAAI,CAAC,YAAY,EAAE;YAClB,SAAS;SACT;QACD,IAAI,YAAY,CAAC,MAAM,KAAK,KAAK,EAAE;YAClC,gBAAgB,CAAC,GAAG,EAAE,CAAC;YACvB,gBAAgB,CAAC,SAAS,IAAI,YAAY,CAAC,WAAW,CAAC;YACvD,IAAI,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE;gBACxE,gBAAgB,CAAC,SAAS,EAAE,CAAC;aAC7B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;YACxB,gBAAgB,CAAC,UAAU,IAAI,YAAY,CAAC,WAAW,CAAC;YACxD,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,MAAA,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnF,IACC,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM;gBACrC,YAAY,CAAC,WAAW,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAChE;gBACD,gBAAgB,CAAC,UAAU,EAAE,CAAC;aAC9B;SACD;aAAM,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM,EAAE;YAC1C,gBAAgB,CAAC,IAAI,EAAE,CAAC;SACxB;QACD,SAAS,CAAC,kBAAkB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;KAClD;IACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;IAC1F,gBAAgB,CAAC,UAAU,GAAG,aAAa,CAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACnE,gBAAgB,CAAC,GAAG,EACpB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,gBAAgB,GAAG,aAAa,CAChD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACzE,gBAAgB,CAAC,SAAS,EAC1B,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EACpE,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IACF,gBAAgB,CAAC,iBAAiB,GAAG,aAAa,CACjD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,EAC1E,gBAAgB,CAAC,UAAU,EAC3B,YAAY,CACZ,CAAC;IAEF,gBAAgB,CAAC,WAAW,GAAG,aAAa,CAC3C,GAAG,GAAG,gBAAgB,CAAC,WAAW,GAAG,gBAAgB,CAAC,UAAU,EAChE,gBAAgB,CAAC,IAAI,EACrB,YAAY,CACZ,CAAC;IAEF,gBAAgB,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC;IAC9G,gBAAgB,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,EAAE,CAAC;IAChH,gBAAgB,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjH,gBAAgB,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,IAAI;QACzD,CAAC,CAAC,gBAAgB,CAAC,UAAU,GAAG,gBAAgB,CAAC,IAAI;QACrD,CAAC,CAAC,CAAC,CAAC;IACL,IAAI,gBAAgB,CAAC,gBAAgB,GAAG,CAAC,IAAI,gBAAgB,CAAC,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE;QAC9G,OAAO,CAAC,IAAI,CAAC,0BAA0B,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;KACvE;IACD,IAAI,gBAAgB,CAAC,iBAAiB,GAAG,CAAC,IAAI,gBAAgB,CAAC,iBAAiB,GAAG,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE;QAClH,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAC;KAC1E;IACD,CAAC,CAAA,MAAA,WAAW,CAAC,OAAO,0CAAE,YAAY,CAAA,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpE,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,gBAAgB,CAAC,cAAc,GAAG,SAAS,CAAC,mBAAmB,EAAE,CAAC;IAClE,OAAO,gBAAgB,CAAC;AACzB,CAAC,CAAC;AAnLW,QAAA,cAAc,kBAmLzB;AAEF,MAAM,aAAa,GAAG,CAAC,YAAoB,EAAE,YAAoB,EAAE,UAAkB,EAAU,EAAE;IAChG,IAAI,YAAY,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC,EAAE;QAC7C,OAAO,IAAI,CAAC;KACZ;IACD,IAAI,YAAY,KAAK,GAAG,IAAI,YAAY,KAAK,UAAU,EAAE;QACxD,OAAO,IAAI,CAAC;KACZ;IACD,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,KAA6B,EAA0B,EAAE;IACnF,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7B,GAAG,MAAM;QACT,YAAY,EAAE,0BAA0B,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC;KACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEW,QAAA,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;CAoBhC,CAAC;AAEF,MAAM,0BAA0B,GAAG,CAClC,YAA2E,EAC3E,SAA4B,EACoC,EAAE;IAClE,OAAO,YAAY,CAAC,MAAM,CACzB,CAAC,OAAO,EAAE,EAAE,CACX,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAChD,yBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,MAAiB,CAAC,KAAK,CAAC,CAAC,CAC5D,CAAC;AACH,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService, CardIds } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { SimulationResult } from './simulation-result';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { Simulator } from './simulation/simulator';\r\nimport { Spectator } from './simulation/spectator/spectator';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nconst cards = new AllCardsService();\r\n\r\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\r\n// the more traditional callback-style handler.\r\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\r\nexport default async (event): Promise<any> => {\r\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\r\n\tawait cards.initializeCardsDb();\r\n\tconst cardsData = new CardsData(cards, false);\r\n\tcardsData.inititialize(\r\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\r\n\t\tbattleInput.gameState?.anomalies ?? [],\r\n\t);\r\n\tconst simulationResult = simulateBattle(battleInput, cards, cardsData);\r\n\r\n\tconst response = {\r\n\t\tstatusCode: 200,\r\n\t\tisBase64Encoded: false,\r\n\t\tbody: JSON.stringify(simulationResult),\r\n\t};\r\n\treturn response;\r\n};\r\n\r\nexport const simulateBattle = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): SimulationResult => {\r\n\tconst start = Date.now();\r\n\r\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\r\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 5000;\r\n\r\n\tconst simulationResult: SimulationResult = {\r\n\t\twonLethal: 0,\r\n\t\twon: 0,\r\n\t\ttied: 0,\r\n\t\tlost: 0,\r\n\t\tlostLethal: 0,\r\n\t\tdamageWon: 0,\r\n\t\tdamageLost: 0,\r\n\t\twonLethalPercent: undefined,\r\n\t\twonPercent: undefined,\r\n\t\ttiedPercent: undefined,\r\n\t\tlostPercent: undefined,\r\n\t\tlostLethalPercent: undefined,\r\n\t\taverageDamageWon: undefined,\r\n\t\taverageDamageLost: undefined,\r\n\t};\r\n\r\n\tconst playerInfo = battleInput.playerBoard;\r\n\tconst opponentInfo = battleInput.opponentBoard;\r\n\r\n\tconst playerBoard = playerInfo.board.map(\r\n\t\t(entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: true } as BoardEntity),\r\n\t);\r\n\tconst playerHand = playerInfo.player.hand?.map(\r\n\t\t(entity) =>\r\n\t\t\t({\r\n\t\t\t\t...addImpliedMechanics(entity, cardsData),\r\n\t\t\t\tfriendly: true,\r\n\t\t\t\tlocked: cardsData.getTavernLevel(entity.cardId) > playerInfo.player.tavernTier,\r\n\t\t\t} as BoardEntity),\r\n\t);\r\n\tplayerInfo.player.secrets = playerInfo.secrets?.filter((e) => !!e?.cardId);\r\n\tplayerInfo.player.friendly = true;\r\n\tconst opponentBoard = opponentInfo.board.map(\r\n\t\t(entity) =>\r\n\t\t\t({\r\n\t\t\t\t...addImpliedMechanics(entity, cardsData),\r\n\t\t\t\tfriendly: false,\r\n\t\t\t\tlocked: cardsData.getTavernLevel(entity.cardId) > playerInfo.player.tavernTier,\r\n\t\t\t} as BoardEntity),\r\n\t);\r\n\tconst opponentHand = opponentInfo.player.hand?.map(\r\n\t\t(entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: true } as BoardEntity),\r\n\t);\r\n\topponentInfo.player.secrets = opponentInfo.secrets?.filter((e) => !!e?.cardId);\r\n\topponentInfo.player.friendly = true;\r\n\r\n\t// When using the simulator, the aura is not applied when receiving the board state. When\r\n\tsetMissingAuras(playerBoard, playerInfo.player, opponentInfo.player, cards);\r\n\tsetMissingAuras(opponentBoard, opponentInfo.player, playerInfo.player, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, cardsData, true);\r\n\tsetImplicitDataHero(opponentInfo.player, cardsData, false);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerInfo.player,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentInfo.player,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tgameState: battleInput.gameState,\r\n\t} as BgsBattleInfo;\r\n\tconst inputStr = JSON.stringify(inputReady);\r\n\tconst spectator = new Spectator(\r\n\t\tbattleInput.playerBoard.player.cardId,\r\n\t\tbattleInput.playerBoard.player.heroPowerId,\r\n\t\tbattleInput.opponentBoard.player.cardId,\r\n\t\tbattleInput.opponentBoard.player.heroPowerId,\r\n\t);\r\n\t!battleInput.options?.skipInfoLogs && console.time('simulation');\r\n\tconst outcomes = {};\r\n\tfor (let i = 0; i < numberOfSimulations; i++) {\r\n\t\tconst simulator = new Simulator(cards, cardsData);\r\n\t\tconst input: BgsBattleInfo = JSON.parse(inputStr);\r\n\t\tconst battleResult = simulator.simulateSingleBattle(\r\n\t\t\tinput.playerBoard.board,\r\n\t\t\tinput.playerBoard.player,\r\n\t\t\tinput.opponentBoard.board,\r\n\t\t\tinput.opponentBoard.player,\r\n\t\t\tinput.gameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tif (Date.now() - start > maxAcceptableDuration) {\r\n\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\r\n\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms', battleResult);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\tif (!battleResult) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (battleResult.result === 'won') {\r\n\t\t\tsimulationResult.won++;\r\n\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\r\n\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\r\n\t\t\t\tsimulationResult.wonLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'lost') {\r\n\t\t\tsimulationResult.lost++;\r\n\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\r\n\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\r\n\t\t\tif (\r\n\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\r\n\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\r\n\t\t\t) {\r\n\t\t\t\tsimulationResult.lostLethal++;\r\n\t\t\t}\r\n\t\t} else if (battleResult.result === 'tied') {\r\n\t\t\tsimulationResult.tied++;\r\n\t\t}\r\n\t\tspectator.commitBattleResult(battleResult.result);\r\n\t}\r\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\r\n\tsimulationResult.wonPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\r\n\t\tsimulationResult.won,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.wonLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.wonLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\r\n\t\tsimulationResult.lost,\r\n\t\ttotalMatches,\r\n\t);\r\n\tsimulationResult.lostLethalPercent = checkRounding(\r\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\r\n\t\tsimulationResult.lostLethal,\r\n\t\ttotalMatches,\r\n\t);\r\n\t// simulationResult.tiedPercent = checkRounding(Math.round((10 * (100 * simulationResult.tied)) / totalMatches) / 10, simulationResult.tied, totalMatches);\r\n\tsimulationResult.tiedPercent = checkRounding(\r\n\t\t100 - simulationResult.lostPercent - simulationResult.wonPercent,\r\n\t\tsimulationResult.tied,\r\n\t\ttotalMatches,\r\n\t);\r\n\r\n\tsimulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\r\n\tsimulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\r\n\tsimulationResult.averageDamageWon = simulationResult.won ? simulationResult.damageWon / simulationResult.won : 0;\r\n\tsimulationResult.averageDamageLost = simulationResult.lost\r\n\t\t? simulationResult.damageLost / simulationResult.lost\r\n\t\t: 0;\r\n\tif (simulationResult.averageDamageWon > 0 && simulationResult.averageDamageWon < playerInfo.player.tavernTier) {\r\n\t\tconsole.warn('average damage won issue', simulationResult, playerInfo);\r\n\t}\r\n\tif (simulationResult.averageDamageLost > 0 && simulationResult.averageDamageLost < opponentInfo.player.tavernTier) {\r\n\t\tconsole.warn('average damage lost issue', simulationResult, opponentInfo);\r\n\t}\r\n\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\r\n\tspectator.prune();\r\n\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples();\r\n\treturn simulationResult;\r\n};\r\n\r\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\r\n\tif (roundedValue === 0 && initialValue !== 0) {\r\n\t\treturn 0.01;\r\n\t}\r\n\tif (roundedValue === 100 && initialValue !== totalValue) {\r\n\t\treturn 99.9;\r\n\t}\r\n\treturn roundedValue;\r\n};\r\n\r\nconst cleanEnchantments = (board: readonly BoardEntity[]): readonly BoardEntity[] => {\r\n\tconst entityIds = board.map((entity) => entity.entityId);\r\n\treturn board.map((entity) => ({\r\n\t\t...entity,\r\n\t\tenchantments: cleanEnchantmentsForEntity(entity.enchantments, entityIds),\r\n\t}));\r\n};\r\n\r\nexport const validEnchantments = [\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\r\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\r\n\tCardIds.LivingSpores_LivingSporesEnchantment,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\r\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\r\n\tCardIds.Sneed_SneedsReplicator,\r\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\r\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\r\n\tCardIds.FireRecollectionEnchantment,\r\n\tCardIds.LightningRecollectionEnchantment,\r\n\tCardIds.WaterRecollectionEnchantment,\r\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\r\n\t// CardIds.FireInvocation_ElementFireEnchantment, // Attack is doubled, probably no use to keep it\r\n\t// CardIds.WaterInvocation_ElementWaterEnchantment, // +3 health and taunt, same\r\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\r\n\tCardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\r\n\tCardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\r\n];\r\n\r\nconst cleanEnchantmentsForEntity = (\r\n\tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\r\n\tentityIds: readonly number[],\r\n): { cardId: string; originEntityId?: number; timing: number }[] => {\r\n\treturn enchantments.filter(\r\n\t\t(enchant) =>\r\n\t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\r\n\t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\r\n\t);\r\n};\r\n"]}
@@ -1,10 +1,13 @@
1
1
  import { BoardEntity } from '../../board-entity';
2
+ import { BoardSecret } from '../../board-secret';
2
3
  export interface GameAction {
3
4
  type: 'damage' | 'attack' | 'spawn' | 'minion-death' | 'power-target' | 'start-of-combat' | 'player-attack' | 'opponent-attack';
4
5
  playerBoard: readonly BoardEntity[];
5
6
  playerHand: readonly BoardEntity[];
7
+ playerSecrets: readonly BoardSecret[];
6
8
  opponentBoard: readonly BoardEntity[];
7
9
  opponentHand: readonly BoardEntity[];
10
+ opponentSecrets: readonly BoardSecret[];
8
11
  sourceEntityId?: number;
9
12
  targetEntityId?: number;
10
13
  targetEntityIds?: number[];
@@ -1 +1 @@
1
- {"version":3,"file":"game-action.js","sourceRoot":"","sources":["../../../src/simulation/spectator/game-action.ts"],"names":[],"mappings":"","sourcesContent":["import { BoardEntity } from '../../board-entity';\r\n\r\nexport interface GameAction {\r\n\ttype:\r\n\t\t| 'damage'\r\n\t\t| 'attack'\r\n\t\t| 'spawn'\r\n\t\t| 'minion-death'\r\n\t\t| 'power-target'\r\n\t\t| 'start-of-combat'\r\n\t\t| 'player-attack'\r\n\t\t| 'opponent-attack';\r\n\tplayerBoard: readonly BoardEntity[];\r\n\tplayerHand: readonly BoardEntity[];\r\n\topponentBoard: readonly BoardEntity[];\r\n\topponentHand: readonly BoardEntity[];\r\n\tsourceEntityId?: number;\r\n\t/** @deprecated */\r\n\ttargetEntityId?: number;\r\n\ttargetEntityIds?: number[];\r\n\r\n\tdamages?: Damage[];\r\n\tspawns?: readonly BoardEntity[];\r\n\tdeaths?: readonly BoardEntity[];\r\n\tdeadMinionsPositionsOnBoard?: readonly number[];\r\n}\r\n\r\nexport interface Damage {\r\n\treadonly sourceEntityId?: number;\r\n\treadonly targetEntityId?: number;\r\n\treadonly damage?: number;\r\n}\r\n"]}
1
+ {"version":3,"file":"game-action.js","sourceRoot":"","sources":["../../../src/simulation/spectator/game-action.ts"],"names":[],"mappings":"","sourcesContent":["import { BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\n\r\nexport interface GameAction {\r\n\ttype:\r\n\t\t| 'damage'\r\n\t\t| 'attack'\r\n\t\t| 'spawn'\r\n\t\t| 'minion-death'\r\n\t\t| 'power-target'\r\n\t\t| 'start-of-combat'\r\n\t\t| 'player-attack'\r\n\t\t| 'opponent-attack';\r\n\tplayerBoard: readonly BoardEntity[];\r\n\tplayerHand: readonly BoardEntity[];\r\n\tplayerSecrets: readonly BoardSecret[];\r\n\topponentBoard: readonly BoardEntity[];\r\n\topponentHand: readonly BoardEntity[];\r\n\topponentSecrets: readonly BoardSecret[];\r\n\tsourceEntityId?: number;\r\n\t/** @deprecated */\r\n\ttargetEntityId?: number;\r\n\ttargetEntityIds?: number[];\r\n\r\n\tdamages?: Damage[];\r\n\tspawns?: readonly BoardEntity[];\r\n\tdeaths?: readonly BoardEntity[];\r\n\tdeadMinionsPositionsOnBoard?: readonly number[];\r\n}\r\n\r\nexport interface Damage {\r\n\treadonly sourceEntityId?: number;\r\n\treadonly targetEntityId?: number;\r\n\treadonly damage?: number;\r\n}\r\n"]}
@@ -68,6 +68,8 @@ class Spectator {
68
68
  const isAttackerFriendly = attackingBoard.every((entity) => entity.friendly);
69
69
  const friendlyBoard = isAttackerFriendly ? attackingBoard : defendingBoard;
70
70
  const opponentBoard = isAttackerFriendly ? defendingBoard : attackingBoard;
71
+ const playerSecrets = isAttackerFriendly ? attackingBoardHero.secrets : defendingBoardHero.secrets;
72
+ const opponentSecrets = isAttackerFriendly ? defendingBoardHero.secrets : attackingBoardHero.secrets;
71
73
  const action = {
72
74
  type: 'attack',
73
75
  sourceEntityId: attackingEntity.entityId,
@@ -76,16 +78,22 @@ class Spectator {
76
78
  playerHand: this.sanitize(isAttackerFriendly ? attackingBoardHero.hand : defendingBoardHero.hand),
77
79
  opponentBoard: this.sanitize(opponentBoard),
78
80
  opponentHand: this.sanitize(isAttackerFriendly ? defendingBoardHero.hand : attackingBoardHero.hand),
81
+ playerSecrets: playerSecrets,
82
+ opponentSecrets: opponentSecrets,
79
83
  };
80
84
  this.addAction(action);
81
85
  }
82
86
  registerStartOfCombat(friendlyBoard, opponentBoard, friendlyHero, opponentHero) {
87
+ const playerSecrets = friendlyHero.secrets;
88
+ const opponentSecrets = opponentHero.secrets;
83
89
  const action = {
84
90
  type: 'start-of-combat',
85
91
  playerBoard: this.sanitize(friendlyBoard),
86
92
  opponentBoard: this.sanitize(opponentBoard),
87
93
  playerHand: this.sanitize(friendlyHero.hand),
88
94
  opponentHand: this.sanitize(opponentHero.hand),
95
+ playerSecrets: playerSecrets,
96
+ opponentSecrets: opponentSecrets,
89
97
  };
90
98
  this.addAction(action);
91
99
  }
@@ -96,6 +104,8 @@ class Spectator {
96
104
  opponentBoard: this.sanitize(opponentBoard),
97
105
  playerHand: null,
98
106
  opponentHand: null,
107
+ playerSecrets: null,
108
+ opponentSecrets: null,
99
109
  damages: [
100
110
  {
101
111
  damage: damage,
@@ -111,6 +121,8 @@ class Spectator {
111
121
  opponentBoard: this.sanitize(opponentBoard),
112
122
  playerHand: null,
113
123
  opponentHand: null,
124
+ playerSecrets: null,
125
+ opponentSecrets: null,
114
126
  damages: [
115
127
  {
116
128
  damage: damage,
@@ -138,11 +150,12 @@ class Spectator {
138
150
  opponentBoard: this.sanitize(opponentBoard),
139
151
  playerHand: null,
140
152
  opponentHand: null,
153
+ playerSecrets: null,
154
+ opponentSecrets: null,
141
155
  };
142
156
  this.addAction(action);
143
157
  }
144
158
  registerPowerTarget(sourceEntity, targetEntity, targetBoard, hero1, hero2) {
145
- var _a;
146
159
  if (!targetEntity) {
147
160
  return;
148
161
  }
@@ -151,8 +164,8 @@ class Spectator {
151
164
  }
152
165
  const friendlyBoard = targetBoard.every((entity) => entity.friendly) ? targetBoard : null;
153
166
  const opponentBoard = targetBoard.every((entity) => !entity.friendly) ? targetBoard : null;
154
- const friendlyHero = ((_a = hero1 === null || hero1 === void 0 ? void 0 : hero1.hand) === null || _a === void 0 ? void 0 : _a.every((entity) => entity.friendly)) ? hero1 : hero2;
155
- const opponentHero = friendlyHero === hero1 ? hero2 : hero1;
167
+ const friendlyHero = (hero1 === null || hero1 === void 0 ? void 0 : hero1.friendly) ? hero1 : (hero2 === null || hero2 === void 0 ? void 0 : hero2.friendly) ? hero2 : null;
168
+ const opponentHero = (hero1 === null || hero1 === void 0 ? void 0 : hero1.friendly) ? hero2 : (hero2 === null || hero2 === void 0 ? void 0 : hero2.friendly) ? hero1 : null;
156
169
  const action = {
157
170
  type: 'power-target',
158
171
  sourceEntityId: sourceEntity.entityId,
@@ -161,6 +174,8 @@ class Spectator {
161
174
  opponentBoard: this.sanitize(opponentBoard),
162
175
  playerHand: this.sanitize(friendlyHero === null || friendlyHero === void 0 ? void 0 : friendlyHero.hand),
163
176
  opponentHand: this.sanitize(opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.hand),
177
+ playerSecrets: friendlyHero === null || friendlyHero === void 0 ? void 0 : friendlyHero.secrets,
178
+ opponentSecrets: opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.secrets,
164
179
  };
165
180
  this.addAction(action);
166
181
  }
@@ -181,6 +196,8 @@ class Spectator {
181
196
  opponentBoard: this.sanitize(opponentBoard),
182
197
  playerHand: null,
183
198
  opponentHand: null,
199
+ playerSecrets: null,
200
+ opponentSecrets: null,
184
201
  };
185
202
  this.addAction(action);
186
203
  }
@@ -200,6 +217,8 @@ class Spectator {
200
217
  opponentBoard: undefined,
201
218
  playerHand: null,
202
219
  opponentHand: null,
220
+ playerSecrets: null,
221
+ opponentSecrets: null,
203
222
  };
204
223
  this.addAction(action);
205
224
  }
@@ -235,6 +254,12 @@ class Spectator {
235
254
  if (lastAction && !action.opponentHand) {
236
255
  action.opponentHand = lastAction.opponentHand;
237
256
  }
257
+ if (lastAction && !action.playerSecrets) {
258
+ action.playerSecrets = lastAction.playerSecrets;
259
+ }
260
+ if (lastAction && !action.opponentSecrets) {
261
+ action.opponentSecrets = lastAction.opponentSecrets;
262
+ }
238
263
  if (lastAction && action.type === 'damage' && lastAction.type === 'attack') {
239
264
  lastAction.damages = lastAction.damages || [];
240
265
  lastAction.damages.push({
@@ -246,6 +271,8 @@ class Spectator {
246
271
  lastAction.opponentBoard = action.opponentBoard;
247
272
  lastAction.playerHand = action.playerHand;
248
273
  lastAction.opponentHand = action.opponentHand;
274
+ lastAction.playerSecrets = action.playerSecrets;
275
+ lastAction.opponentSecrets = action.opponentSecrets;
249
276
  }
250
277
  else if (lastAction && action.type === 'damage' && lastAction.type === 'damage') {
251
278
  lastAction.damages = lastAction.damages || [];
@@ -258,6 +285,8 @@ class Spectator {
258
285
  lastAction.opponentBoard = action.opponentBoard;
259
286
  lastAction.playerHand = action.playerHand;
260
287
  lastAction.opponentHand = action.opponentHand;
288
+ lastAction.playerSecrets = action.playerSecrets;
289
+ lastAction.opponentSecrets = action.opponentSecrets;
261
290
  }
262
291
  else if (lastAction &&
263
292
  action.type === 'power-target' &&
@@ -272,6 +301,8 @@ class Spectator {
272
301
  lastAction.opponentBoard = action.opponentBoard;
273
302
  lastAction.playerHand = action.playerHand;
274
303
  lastAction.opponentHand = action.opponentHand;
304
+ lastAction.playerSecrets = action.playerSecrets;
305
+ lastAction.opponentSecrets = action.opponentSecrets;
275
306
  }
276
307
  else {
277
308
  result.push(action);
@@ -1 +1 @@
1
- {"version":3,"file":"spectator.js","sourceRoot":"","sources":["../../../src/simulation/spectator/spectator.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity } from 'src/bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { GameAction } from './game-action';\r\nimport { GameSample } from './game-sample';\r\n\r\nconst MAX_SAMPLES = 1;\r\n\r\nexport class Spectator {\r\n\tprivate actionsForCurrentBattle: GameAction[];\r\n\tprivate wonBattles: GameSample[];\r\n\tprivate tiedBattles: GameSample[];\r\n\tprivate lostBattles: GameSample[];\r\n\r\n\tconstructor(\r\n\t\tprivate readonly playerCardId?: string,\r\n\t\tprivate readonly playerHeroPowerCardId?: string,\r\n\t\tprivate readonly opponentCardId?: string,\r\n\t\tprivate readonly opponentHeroPowerCardId?: string,\r\n\t) {\r\n\t\tthis.actionsForCurrentBattle = [];\r\n\t\tthis.wonBattles = [];\r\n\t\tthis.tiedBattles = [];\r\n\t\tthis.lostBattles = [];\r\n\t}\r\n\r\n\tpublic prune(): void {\r\n\t\tthis.wonBattles = this.wonBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.lostBattles = this.lostBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.tiedBattles = this.tiedBattles.slice(0, MAX_SAMPLES);\r\n\t}\r\n\r\n\tpublic buildOutcomeSamples(): {\r\n\t\twon: readonly GameSample[];\r\n\t\tlost: readonly GameSample[];\r\n\t\ttied: readonly GameSample[];\r\n\t} {\r\n\t\treturn {\r\n\t\t\twon: this.wonBattles,\r\n\t\t\tlost: this.lostBattles,\r\n\t\t\ttied: this.tiedBattles,\r\n\t\t};\r\n\t}\r\n\r\n\tpublic commitBattleResult(result: 'won' | 'lost' | 'tied'): void {\r\n\t\tif (\r\n\t\t\tthis.wonBattles.length >= MAX_SAMPLES &&\r\n\t\t\tthis.lostBattles.length >= MAX_SAMPLES &&\r\n\t\t\tthis.tiedBattles.length >= MAX_SAMPLES\r\n\t\t) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// const actionsForBattle = this.collapseActions(this.actionsForCurrentBattle);\r\n\t\tconst actionsForBattle = this.actionsForCurrentBattle;\r\n\t\tthis.actionsForCurrentBattle = [];\r\n\r\n\t\tswitch (result) {\r\n\t\t\tcase 'won':\r\n\t\t\t\tthis.wonBattles.push({\r\n\t\t\t\t\tactions: actionsForBattle,\r\n\t\t\t\t\tplayerCardId: this.playerCardId,\r\n\t\t\t\t\tplayerHeroPowerCardId: this.playerHeroPowerCardId,\r\n\t\t\t\t\topponentCardId: this.opponentCardId,\r\n\t\t\t\t\topponentHeroPowerCardId: this.opponentHeroPowerCardId,\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'lost':\r\n\t\t\t\tthis.lostBattles.push({\r\n\t\t\t\t\tactions: actionsForBattle,\r\n\t\t\t\t\tplayerCardId: this.playerCardId,\r\n\t\t\t\t\tplayerHeroPowerCardId: this.playerHeroPowerCardId,\r\n\t\t\t\t\topponentCardId: this.opponentCardId,\r\n\t\t\t\t\topponentHeroPowerCardId: this.opponentHeroPowerCardId,\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tied':\r\n\t\t\t\tthis.tiedBattles.push({\r\n\t\t\t\t\tactions: actionsForBattle,\r\n\t\t\t\t\tplayerCardId: this.playerCardId,\r\n\t\t\t\t\tplayerHeroPowerCardId: this.playerHeroPowerCardId,\r\n\t\t\t\t\topponentCardId: this.opponentCardId,\r\n\t\t\t\t\topponentHeroPowerCardId: this.opponentHeroPowerCardId,\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic registerAttack(\r\n\t\tattackingEntity: BoardEntity,\r\n\t\tdefendingEntity: BoardEntity,\r\n\t\tattackingBoard: readonly BoardEntity[],\r\n\t\tdefendingBoard: readonly BoardEntity[],\r\n\t\tattackingBoardHero: BgsPlayerEntity,\r\n\t\tdefendingBoardHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tconst isAttackerFriendly = attackingBoard.every((entity) => entity.friendly);\r\n\t\tconst friendlyBoard = isAttackerFriendly ? attackingBoard : defendingBoard;\r\n\t\tconst opponentBoard = isAttackerFriendly ? defendingBoard : attackingBoard;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'attack',\r\n\t\t\tsourceEntityId: attackingEntity.entityId,\r\n\t\t\ttargetEntityId: defendingEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\tplayerHand: this.sanitize(isAttackerFriendly ? attackingBoardHero.hand : defendingBoardHero.hand),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\topponentHand: this.sanitize(isAttackerFriendly ? defendingBoardHero.hand : attackingBoardHero.hand),\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerStartOfCombat(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tfriendlyHero: BgsPlayerEntity,\r\n\t\topponentHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'start-of-combat',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero.hand),\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPlayerAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'player-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerOpponentAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'opponent-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDamageDealt(\r\n\t\tdamagingEntity: BoardEntity,\r\n\t\tdamagedEntity: BoardEntity,\r\n\t\tdamageTaken: number,\r\n\t\tdamagedEntityBoard: BoardEntity[],\r\n\t): void {\r\n\t\tif (!damagingEntity.entityId) {\r\n\t\t\tconsole.error('missing damaging entity id', damagingEntity.cardId);\r\n\t\t}\r\n\t\tconst friendlyBoard = damagedEntityBoard.every((entity) => entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst opponentBoard = damagedEntityBoard.every((entity) => !entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'damage',\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tsourceEntityId: damagingEntity.entityId,\r\n\t\t\t\t\ttargetEntityId: damagedEntity.entityId,\r\n\t\t\t\t\tdamage: damageTaken,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPowerTarget(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity,\r\n\t\ttargetEntity: BoardEntity,\r\n\t\ttargetBoard: BoardEntity[],\r\n\t\thero1: BgsPlayerEntity,\r\n\t\thero2: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!targetEntity) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!sourceEntity.entityId && !(sourceEntity as BgsPlayerEntity).heroPowerId) {\r\n\t\t\tconsole.error('missing damaging entity id', sourceEntity.cardId);\r\n\t\t}\r\n\t\t// console.log('registerPowerTarget', stringifySimpleCard(sourceEntity), stringifySimpleCard(targetEntity), new Error().stack);\r\n\t\tconst friendlyBoard = targetBoard.every((entity) => entity.friendly) ? targetBoard : null;\r\n\t\tconst opponentBoard = targetBoard.every((entity) => !entity.friendly) ? targetBoard : null;\r\n\t\tconst friendlyHero = hero1?.hand?.every((entity) => entity.friendly) ? hero1 : hero2;\r\n\t\tconst opponentHero = friendlyHero === hero1 ? hero2 : hero1;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'power-target',\r\n\t\t\tsourceEntityId: sourceEntity.entityId,\r\n\t\t\ttargetEntityId: targetEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero?.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero?.hand),\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerMinionsSpawn(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity,\r\n\t\tboardOnWhichToSpawn: BoardEntity[],\r\n\t\tspawnedEntities: readonly BoardEntity[],\r\n\t): void {\r\n\t\tif (!spawnedEntities || spawnedEntities.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!sourceEntity.entityId) {\r\n\t\t\tconsole.error('missing spawn source entity id', sourceEntity);\r\n\t\t}\r\n\t\tconst friendlyBoard = boardOnWhichToSpawn.every((entity) => entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst opponentBoard = boardOnWhichToSpawn.every((entity) => !entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'spawn',\r\n\t\t\tspawns: this.sanitize(spawnedEntities),\r\n\t\t\tsourceEntityId: sourceEntity?.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDeadEntities(\r\n\t\tdeadMinionIndexes1: number[],\r\n\t\tdeadEntities1: BoardEntity[],\r\n\t\tboard1: BoardEntity[],\r\n\t\tdeadMinionIndexes2: number[],\r\n\t\tdeadEntities2: BoardEntity[],\r\n\t\tboard2: BoardEntity[],\r\n\t): void {\r\n\t\tconst deaths = [...(deadEntities1 || []), ...(deadEntities2 || [])];\r\n\t\tif (!deaths || deaths.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'minion-death',\r\n\t\t\tdeaths: this.sanitize(deaths),\r\n\t\t\tdeadMinionsPositionsOnBoard: [\r\n\t\t\t\t...(deadMinionIndexes1 || []).map((i) => board1.length - i),\r\n\t\t\t\t...(deadMinionIndexes2 || []).map((i) => board2.length - i),\r\n\t\t\t],\r\n\t\t\tplayerBoard: undefined,\r\n\t\t\topponentBoard: undefined,\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tprivate addAction(action: GameAction) {\r\n\t\tif (!this.actionsForCurrentBattle.length) {\r\n\t\t\tthis.actionsForCurrentBattle.push(action);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst collapsed = this.collapseActions([\r\n\t\t\tthis.actionsForCurrentBattle[this.actionsForCurrentBattle.length - 1],\r\n\t\t\taction,\r\n\t\t]);\r\n\t\tthis.actionsForCurrentBattle.splice(this.actionsForCurrentBattle.length - 1, 1, ...collapsed);\r\n\t}\r\n\r\n\tprivate collapseActions(actions: readonly GameAction[]): readonly GameAction[] {\r\n\t\tif (!actions || actions.length === 0) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\t\tconst result: GameAction[] = [];\r\n\t\tfor (let i = 0; i < actions.length; i++) {\r\n\t\t\tconst action = actions[i];\r\n\t\t\tconst lastAction = result.length > 0 ? result[result.length - 1] : null;\r\n\r\n\t\t\tif (lastAction && !action.playerBoard) {\r\n\t\t\t\taction.playerBoard = lastAction.playerBoard;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.opponentBoard) {\r\n\t\t\t\taction.opponentBoard = lastAction.opponentBoard;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.playerHand) {\r\n\t\t\t\taction.playerHand = lastAction.playerHand;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.opponentHand) {\r\n\t\t\t\taction.opponentHand = lastAction.opponentHand;\r\n\t\t\t}\r\n\r\n\t\t\tif (lastAction && action.type === 'damage' && lastAction.type === 'attack') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t} else if (lastAction && action.type === 'damage' && lastAction.type === 'damage') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t} else if (\r\n\t\t\t\tlastAction &&\r\n\t\t\t\taction.type === 'power-target' &&\r\n\t\t\t\tlastAction.type === 'power-target' &&\r\n\t\t\t\taction.sourceEntityId === lastAction.sourceEntityId\r\n\t\t\t) {\r\n\t\t\t\tlastAction.targetEntityIds =\r\n\t\t\t\t\tlastAction.targetEntityIds ?? (lastAction.targetEntityId ? [lastAction.targetEntityId] : []);\r\n\t\t\t\taction.targetEntityIds =\r\n\t\t\t\t\taction.targetEntityIds ?? (action.targetEntityId ? [action.targetEntityId] : []);\r\n\t\t\t\tlastAction.targetEntityIds.push(...action.targetEntityIds);\r\n\t\t\t\t// So that when multiple Leapfroggers enchantments target the same minion,\r\n\t\t\t\t// we can count them in the replay viewer's text\r\n\t\t\t\t// lastAction.targetEntityIds = [...new Set(lastAction.targetEntityIds)];\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(action);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\t// Calling sanitize every time before we add an action to the list is mandatory, since\r\n\t// the entities and boards are mutable\r\n\tprivate sanitize(board: readonly BoardEntity[]): readonly BoardEntity[] {\r\n\t\tif (!board) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\treturn board.map(\r\n\t\t\t(entity) =>\r\n\t\t\t\t({\r\n\t\t\t\t\t...entity,\r\n\t\t\t\t\tenchantments: undefined,\r\n\t\t\t\t\tcantAttack: undefined,\r\n\t\t\t\t\tattacksPerformed: undefined,\r\n\t\t\t\t\tattackImmediately: undefined,\r\n\t\t\t\t\tpreviousAttack: undefined,\r\n\t\t\t\t\tlastAffectedByEntity: undefined,\r\n\t\t\t\t\tattacking: undefined,\r\n\t\t\t\t} as BoardEntity),\r\n\t\t);\r\n\t}\r\n}\r\n"]}
1
+ {"version":3,"file":"spectator.js","sourceRoot":"","sources":["../../../src/simulation/spectator/spectator.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity } from 'src/bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { GameAction } from './game-action';\r\nimport { GameSample } from './game-sample';\r\n\r\nconst MAX_SAMPLES = 1;\r\n\r\nexport class Spectator {\r\n\tprivate actionsForCurrentBattle: GameAction[];\r\n\tprivate wonBattles: GameSample[];\r\n\tprivate tiedBattles: GameSample[];\r\n\tprivate lostBattles: GameSample[];\r\n\r\n\tconstructor(\r\n\t\tprivate readonly playerCardId?: string,\r\n\t\tprivate readonly playerHeroPowerCardId?: string,\r\n\t\tprivate readonly opponentCardId?: string,\r\n\t\tprivate readonly opponentHeroPowerCardId?: string,\r\n\t) {\r\n\t\tthis.actionsForCurrentBattle = [];\r\n\t\tthis.wonBattles = [];\r\n\t\tthis.tiedBattles = [];\r\n\t\tthis.lostBattles = [];\r\n\t}\r\n\r\n\tpublic prune(): void {\r\n\t\tthis.wonBattles = this.wonBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.lostBattles = this.lostBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.tiedBattles = this.tiedBattles.slice(0, MAX_SAMPLES);\r\n\t}\r\n\r\n\tpublic buildOutcomeSamples(): {\r\n\t\twon: readonly GameSample[];\r\n\t\tlost: readonly GameSample[];\r\n\t\ttied: readonly GameSample[];\r\n\t} {\r\n\t\treturn {\r\n\t\t\twon: this.wonBattles,\r\n\t\t\tlost: this.lostBattles,\r\n\t\t\ttied: this.tiedBattles,\r\n\t\t};\r\n\t}\r\n\r\n\tpublic commitBattleResult(result: 'won' | 'lost' | 'tied'): void {\r\n\t\tif (\r\n\t\t\tthis.wonBattles.length >= MAX_SAMPLES &&\r\n\t\t\tthis.lostBattles.length >= MAX_SAMPLES &&\r\n\t\t\tthis.tiedBattles.length >= MAX_SAMPLES\r\n\t\t) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// const actionsForBattle = this.collapseActions(this.actionsForCurrentBattle);\r\n\t\tconst actionsForBattle = this.actionsForCurrentBattle;\r\n\t\tthis.actionsForCurrentBattle = [];\r\n\r\n\t\tswitch (result) {\r\n\t\t\tcase 'won':\r\n\t\t\t\tthis.wonBattles.push({\r\n\t\t\t\t\tactions: actionsForBattle,\r\n\t\t\t\t\tplayerCardId: this.playerCardId,\r\n\t\t\t\t\tplayerHeroPowerCardId: this.playerHeroPowerCardId,\r\n\t\t\t\t\topponentCardId: this.opponentCardId,\r\n\t\t\t\t\topponentHeroPowerCardId: this.opponentHeroPowerCardId,\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'lost':\r\n\t\t\t\tthis.lostBattles.push({\r\n\t\t\t\t\tactions: actionsForBattle,\r\n\t\t\t\t\tplayerCardId: this.playerCardId,\r\n\t\t\t\t\tplayerHeroPowerCardId: this.playerHeroPowerCardId,\r\n\t\t\t\t\topponentCardId: this.opponentCardId,\r\n\t\t\t\t\topponentHeroPowerCardId: this.opponentHeroPowerCardId,\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tied':\r\n\t\t\t\tthis.tiedBattles.push({\r\n\t\t\t\t\tactions: actionsForBattle,\r\n\t\t\t\t\tplayerCardId: this.playerCardId,\r\n\t\t\t\t\tplayerHeroPowerCardId: this.playerHeroPowerCardId,\r\n\t\t\t\t\topponentCardId: this.opponentCardId,\r\n\t\t\t\t\topponentHeroPowerCardId: this.opponentHeroPowerCardId,\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic registerAttack(\r\n\t\tattackingEntity: BoardEntity,\r\n\t\tdefendingEntity: BoardEntity,\r\n\t\tattackingBoard: readonly BoardEntity[],\r\n\t\tdefendingBoard: readonly BoardEntity[],\r\n\t\tattackingBoardHero: BgsPlayerEntity,\r\n\t\tdefendingBoardHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tconst isAttackerFriendly = attackingBoard.every((entity) => entity.friendly);\r\n\t\tconst friendlyBoard = isAttackerFriendly ? attackingBoard : defendingBoard;\r\n\t\tconst opponentBoard = isAttackerFriendly ? defendingBoard : attackingBoard;\r\n\t\tconst playerSecrets = isAttackerFriendly ? attackingBoardHero.secrets : defendingBoardHero.secrets;\r\n\t\tconst opponentSecrets = isAttackerFriendly ? defendingBoardHero.secrets : attackingBoardHero.secrets;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'attack',\r\n\t\t\tsourceEntityId: attackingEntity.entityId,\r\n\t\t\ttargetEntityId: defendingEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\tplayerHand: this.sanitize(isAttackerFriendly ? attackingBoardHero.hand : defendingBoardHero.hand),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\topponentHand: this.sanitize(isAttackerFriendly ? defendingBoardHero.hand : attackingBoardHero.hand),\r\n\t\t\tplayerSecrets: playerSecrets,\r\n\t\t\topponentSecrets: opponentSecrets,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerStartOfCombat(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tfriendlyHero: BgsPlayerEntity,\r\n\t\topponentHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tconst playerSecrets = friendlyHero.secrets;\r\n\t\tconst opponentSecrets = opponentHero.secrets;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'start-of-combat',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero.hand),\r\n\t\t\tplayerSecrets: playerSecrets,\r\n\t\t\topponentSecrets: opponentSecrets,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPlayerAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'player-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tplayerSecrets: null,\r\n\t\t\topponentSecrets: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerOpponentAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'opponent-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tplayerSecrets: null,\r\n\t\t\topponentSecrets: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDamageDealt(\r\n\t\tdamagingEntity: BoardEntity,\r\n\t\tdamagedEntity: BoardEntity,\r\n\t\tdamageTaken: number,\r\n\t\tdamagedEntityBoard: BoardEntity[],\r\n\t): void {\r\n\t\tif (!damagingEntity.entityId) {\r\n\t\t\tconsole.error('missing damaging entity id', damagingEntity.cardId);\r\n\t\t}\r\n\t\tconst friendlyBoard = damagedEntityBoard.every((entity) => entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst opponentBoard = damagedEntityBoard.every((entity) => !entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'damage',\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tsourceEntityId: damagingEntity.entityId,\r\n\t\t\t\t\ttargetEntityId: damagedEntity.entityId,\r\n\t\t\t\t\tdamage: damageTaken,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tplayerSecrets: null,\r\n\t\t\topponentSecrets: null,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPowerTarget(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity,\r\n\t\ttargetEntity: BoardEntity,\r\n\t\ttargetBoard: BoardEntity[],\r\n\t\thero1: BgsPlayerEntity,\r\n\t\thero2: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!targetEntity) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!sourceEntity.entityId && !(sourceEntity as BgsPlayerEntity).heroPowerId) {\r\n\t\t\tconsole.error('missing damaging entity id', sourceEntity.cardId);\r\n\t\t}\r\n\t\t// console.log('registerPowerTarget', stringifySimpleCard(sourceEntity), stringifySimpleCard(targetEntity), new Error().stack);\r\n\t\tconst friendlyBoard = targetBoard.every((entity) => entity.friendly) ? targetBoard : null;\r\n\t\tconst opponentBoard = targetBoard.every((entity) => !entity.friendly) ? targetBoard : null;\r\n\t\tconst friendlyHero = hero1?.friendly ? hero1 : hero2?.friendly ? hero2 : null;\r\n\t\tconst opponentHero = hero1?.friendly ? hero2 : hero2?.friendly ? hero1 : null;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'power-target',\r\n\t\t\tsourceEntityId: sourceEntity.entityId,\r\n\t\t\ttargetEntityId: targetEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero?.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero?.hand),\r\n\t\t\tplayerSecrets: friendlyHero?.secrets,\r\n\t\t\topponentSecrets: opponentHero?.secrets,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerMinionsSpawn(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity,\r\n\t\tboardOnWhichToSpawn: BoardEntity[],\r\n\t\tspawnedEntities: readonly BoardEntity[],\r\n\t): void {\r\n\t\tif (!spawnedEntities || spawnedEntities.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!sourceEntity.entityId) {\r\n\t\t\tconsole.error('missing spawn source entity id', sourceEntity);\r\n\t\t}\r\n\t\tconst friendlyBoard = boardOnWhichToSpawn.every((entity) => entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst opponentBoard = boardOnWhichToSpawn.every((entity) => !entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'spawn',\r\n\t\t\tspawns: this.sanitize(spawnedEntities),\r\n\t\t\tsourceEntityId: sourceEntity?.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tplayerSecrets: null,\r\n\t\t\topponentSecrets: null,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDeadEntities(\r\n\t\tdeadMinionIndexes1: number[],\r\n\t\tdeadEntities1: BoardEntity[],\r\n\t\tboard1: BoardEntity[],\r\n\t\tdeadMinionIndexes2: number[],\r\n\t\tdeadEntities2: BoardEntity[],\r\n\t\tboard2: BoardEntity[],\r\n\t): void {\r\n\t\tconst deaths = [...(deadEntities1 || []), ...(deadEntities2 || [])];\r\n\t\tif (!deaths || deaths.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = {\r\n\t\t\ttype: 'minion-death',\r\n\t\t\tdeaths: this.sanitize(deaths),\r\n\t\t\tdeadMinionsPositionsOnBoard: [\r\n\t\t\t\t...(deadMinionIndexes1 || []).map((i) => board1.length - i),\r\n\t\t\t\t...(deadMinionIndexes2 || []).map((i) => board2.length - i),\r\n\t\t\t],\r\n\t\t\tplayerBoard: undefined,\r\n\t\t\topponentBoard: undefined,\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tplayerSecrets: null,\r\n\t\t\topponentSecrets: null,\r\n\t\t};\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tprivate addAction(action: GameAction) {\r\n\t\tif (!this.actionsForCurrentBattle.length) {\r\n\t\t\tthis.actionsForCurrentBattle.push(action);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst collapsed = this.collapseActions([\r\n\t\t\tthis.actionsForCurrentBattle[this.actionsForCurrentBattle.length - 1],\r\n\t\t\taction,\r\n\t\t]);\r\n\t\tthis.actionsForCurrentBattle.splice(this.actionsForCurrentBattle.length - 1, 1, ...collapsed);\r\n\t}\r\n\r\n\tprivate collapseActions(actions: readonly GameAction[]): readonly GameAction[] {\r\n\t\tif (!actions || actions.length === 0) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\t\tconst result: GameAction[] = [];\r\n\t\tfor (let i = 0; i < actions.length; i++) {\r\n\t\t\tconst action = actions[i];\r\n\t\t\tconst lastAction = result.length > 0 ? result[result.length - 1] : null;\r\n\r\n\t\t\tif (lastAction && !action.playerBoard) {\r\n\t\t\t\taction.playerBoard = lastAction.playerBoard;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.opponentBoard) {\r\n\t\t\t\taction.opponentBoard = lastAction.opponentBoard;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.playerHand) {\r\n\t\t\t\taction.playerHand = lastAction.playerHand;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.opponentHand) {\r\n\t\t\t\taction.opponentHand = lastAction.opponentHand;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.playerSecrets) {\r\n\t\t\t\taction.playerSecrets = lastAction.playerSecrets;\r\n\t\t\t}\r\n\t\t\tif (lastAction && !action.opponentSecrets) {\r\n\t\t\t\taction.opponentSecrets = lastAction.opponentSecrets;\r\n\t\t\t}\r\n\r\n\t\t\tif (lastAction && action.type === 'damage' && lastAction.type === 'attack') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t} else if (lastAction && action.type === 'damage' && lastAction.type === 'damage') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t} else if (\r\n\t\t\t\tlastAction &&\r\n\t\t\t\taction.type === 'power-target' &&\r\n\t\t\t\tlastAction.type === 'power-target' &&\r\n\t\t\t\taction.sourceEntityId === lastAction.sourceEntityId\r\n\t\t\t) {\r\n\t\t\t\tlastAction.targetEntityIds =\r\n\t\t\t\t\tlastAction.targetEntityIds ?? (lastAction.targetEntityId ? [lastAction.targetEntityId] : []);\r\n\t\t\t\taction.targetEntityIds =\r\n\t\t\t\t\taction.targetEntityIds ?? (action.targetEntityId ? [action.targetEntityId] : []);\r\n\t\t\t\tlastAction.targetEntityIds.push(...action.targetEntityIds);\r\n\t\t\t\t// So that when multiple Leapfroggers enchantments target the same minion,\r\n\t\t\t\t// we can count them in the replay viewer's text\r\n\t\t\t\t// lastAction.targetEntityIds = [...new Set(lastAction.targetEntityIds)];\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(action);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result;\r\n\t}\r\n\r\n\t// Calling sanitize every time before we add an action to the list is mandatory, since\r\n\t// the entities and boards are mutable\r\n\tprivate sanitize(board: readonly BoardEntity[]): readonly BoardEntity[] {\r\n\t\tif (!board) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\treturn board.map(\r\n\t\t\t(entity) =>\r\n\t\t\t\t({\r\n\t\t\t\t\t...entity,\r\n\t\t\t\t\tenchantments: undefined,\r\n\t\t\t\t\tcantAttack: undefined,\r\n\t\t\t\t\tattacksPerformed: undefined,\r\n\t\t\t\t\tattackImmediately: undefined,\r\n\t\t\t\t\tpreviousAttack: undefined,\r\n\t\t\t\t\tlastAffectedByEntity: undefined,\r\n\t\t\t\t\tattacking: undefined,\r\n\t\t\t\t} as BoardEntity),\r\n\t\t);\r\n\t}\r\n}\r\n"]}
@@ -632,15 +632,8 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
632
632
  break;
633
633
  }
634
634
  const target = targets[0];
635
- let battleAttacker = attacker;
636
- let battleDefender = target;
637
- while (battleAttacker.health > 0 &&
638
- battleDefender.health > 0 &&
639
- !battleAttacker.definitelyDead &&
640
- !battleDefender.definitelyDead) {
641
- (0, attack_1.doFullAttack)(battleAttacker, attackingBoard, attackingBoardHero, battleDefender, defendingBoard, defendingBoardHero, allCards, cardsData, sharedState, spectator);
642
- battleAttacker = target;
643
- battleDefender = attacker;
635
+ while (attacker.health > 0 && target.health > 0 && !attacker.definitelyDead && !target.definitelyDead) {
636
+ (0, attack_1.doFullAttack)(attacker, attackingBoard, attackingBoardHero, target, defendingBoard, defendingBoardHero, allCards, cardsData, sharedState, spectator);
644
637
  }
645
638
  }
646
639
  }
@@ -1 +1 @@
1
- {"version":3,"file":"start-of-combat.js","sourceRoot":"","sources":["../../src/simulation/start-of-combat.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { ALL_BG_RACES, AllCardsService, CardIds, Race } from '@firestone-hs/reference-data';\r\nimport { BgsGameState } from '../bgs-battle-info';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardsData, START_OF_COMBAT_CARD_IDS } from '../cards/cards-data';\r\nimport { pickRandom, pickRandomLowestHealth, shuffleArray } from '../services/utils';\r\nimport {\r\n\tafterStatsUpdate,\r\n\thasCorrectTribe,\r\n\tisCorrectTribe,\r\n\tmakeMinionGolden,\r\n\tmodifyAttack,\r\n\tmodifyHealth,\r\n\tupdateDivineShield,\r\n} from '../utils';\r\nimport { removeAurasFromSelf } from './add-minion-to-board';\r\nimport {\r\n\tdealDamageToEnemy,\r\n\tdealDamageToRandomEnemy,\r\n\tdoFullAttack,\r\n\tfindNearestEnemies,\r\n\tgetNeighbours,\r\n\tperformEntitySpawns,\r\n\tprocessMinionDeath,\r\n\tsimulateAttack,\r\n} from './attack';\r\nimport {\r\n\tapplyEarthInvocationEnchantment,\r\n\tapplyFireInvocationEnchantment,\r\n\tapplyLightningInvocationEnchantment,\r\n\tapplyWaterInvocationEnchantment,\r\n\thandleDeathrattles,\r\n} from './deathrattle-effects';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { SharedState } from './shared-state';\r\nimport { Spectator } from './spectator/spectator';\r\n\r\nexport const handleStartOfCombat = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// https://twitter.com/DCalkosz/status/1564705111850434561\r\n\tcurrentAttacker = handleStartOfCombatQuestRewards(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatSpells(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatAnomalies(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\t// https://twitter.com/DCalkosz/status/1488361384320528388?s=20&t=1ECxRZFdjqwEa2fRsXk32Q\r\n\t// There’s a certain order for Start of Combat hero powers, rather than “coin flips” where\r\n\t// an unlucky trigger order could mess up some positioning you had planned for your own hero\r\n\t// power. “Precombat” (Al’Akir, Y’Shaarj), then Illidan, then others.\r\n\t// Update: this seems to have changed: https://x.com/LoewenMitchell/status/1737588920139825335?s=20\r\n\t// now you have all hero powers trigger in a first phase, then you have Illidan, and once everything has triggered, you have Tavish\r\n\tcurrentAttacker = handlePreCombatHeroPowers(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\t// Because start of combat powers like Red Whelp's use the board composition before Illidan's strike to know the amount of damage\r\n\tconst playerBoardBefore = playerBoard.map((e) => ({ ...e }));\r\n\tconst opponentBoardBefore = opponentBoard.map((e) => ({ ...e }));\r\n\tcurrentAttacker = handleIllidanHeroPowers(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatHeroPowers(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatMinions(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tplayerBoardBefore,\r\n\t\topponentBoardBefore,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handlePreCombatHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (Math.random() < 0.5) {\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else {\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handlePreCombatHeroPowersForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\t// Some are part of the incoming board: Y'Shaarj, Lich King, Ozumat\r\n\t// Since the order is not important here, we just always do the player first\r\n\tconst playerHeroPowerId = playerEntity.heroPowerId || getHeroPowerForHero(playerEntity.cardId);\r\n\tif (playerHeroPowerId === CardIds.SwattingInsects && playerBoard.length > 0) {\r\n\t\t// Should be sent by the app, but it is an idempotent operation, so we can just reapply it here\r\n\t\thandleAlakirForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.EarthInvocationToken) {\r\n\t\tapplyEarthInvocationEnchantment(playerBoard, null, playerEntity, allCards, sharedState, spectator);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.WaterInvocationToken) {\r\n\t\tapplyWaterInvocationEnchantment(playerBoard, null, playerEntity, allCards, spectator);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.FireInvocationToken) {\r\n\t\tapplyFireInvocationEnchantment(playerBoard, null, playerEntity, allCards, spectator);\r\n\t} else if (playerHeroPowerId === CardIds.AllWillBurn) {\r\n\t\tapplyAllWillBurn(playerBoard, opponentBoard, playerEntity, allCards, spectator);\r\n\t} else if (playerHeroPowerId === CardIds.Ozumat_Tentacular) {\r\n\t\thandleOzumatForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tfriendly,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.TamsinRoame_FragrantPhylactery) {\r\n\t\thandleTamsinForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// Tamsin's hero power somehow happens before the current attacker is chosen.\r\n\t\t// See http://replays.firestoneapp.com/?reviewId=bce94e6b-c807-48e4-9c72-2c5c04421213&turn=6&action=9\r\n\t\t// Even worse: if a scallywag token pops, it attacks before the first attacker is recomputed\r\n\t\tshouldRecomputeCurrentAttacker = true;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.TeronGorefiend_RapidReanimation) {\r\n\t\thandleTeronForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// Same as Tamsin? No, because the new minion should repop automatically\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.WaxWarband) {\r\n\t\thandleWaxWarbandForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.LightningInvocationToken) {\r\n\t\tapplyLightningInvocationEnchantment(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tnull,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\r\n\tprocessMinionDeath(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n\tif (shouldRecomputeCurrentAttacker) {\r\n\t\tconst previousCurrentAttacker = currentAttacker;\r\n\t\tcurrentAttacker =\r\n\t\t\tplayerBoard.length > opponentBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: 1\r\n\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: 0\r\n\t\t\t\t: currentAttacker;\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nexport const handleIllidanHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// console.log('current attacker before', currentAttacker);\r\n\t// Apparently it's a toin coss about whether to handle Illidan first or Al'Akir first\r\n\t// Auras are only relevant for Illidan, and already applied there\r\n\tif (Math.random() < 0.5) {\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else {\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\tprocessMinionDeath(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n\t// console.log('current attacker after', currentAttacker);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatMinions = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tplayerBoardBefore: BoardEntity[],\r\n\topponentBoardBefore: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tlet attackerForStart = currentAttacker;\r\n\tconst playerAttackers = playerBoard.filter((entity) => START_OF_COMBAT_CARD_IDS.includes(entity.cardId as CardIds));\r\n\tconst opponentAttackers = opponentBoard.filter((entity) =>\r\n\t\tSTART_OF_COMBAT_CARD_IDS.includes(entity.cardId as CardIds),\r\n\t);\r\n\r\n\twhile (playerAttackers.length > 0 || opponentAttackers.length > 0) {\r\n\t\tif (attackerForStart === 0 && playerAttackers.length > 0) {\r\n\t\t\tconst attacker = playerAttackers.splice(0, 1)[0];\r\n\t\t\tif (attacker.health <= 0 || attacker.definitelyDead) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tperformStartOfCombatMinionsForPlayer(\r\n\t\t\t\tattacker,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tplayerBoardBefore,\r\n\t\t\t\topponentBoardBefore,\r\n\t\t\t\tallCards,\r\n\t\t\t\tspawns,\r\n\t\t\t\tsharedState,\r\n\t\t\t\tgameState,\r\n\t\t\t\tspectator,\r\n\t\t\t);\r\n\t\t} else if (attackerForStart === 1 && opponentAttackers.length > 0) {\r\n\t\t\tconst attacker = opponentAttackers.splice(0, 1)[0];\r\n\t\t\tif (attacker.health <= 0 || attacker.definitelyDead) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tperformStartOfCombatMinionsForPlayer(\r\n\t\t\t\tattacker,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\topponentBoardBefore,\r\n\t\t\t\tplayerBoardBefore,\r\n\t\t\t\tallCards,\r\n\t\t\t\tspawns,\r\n\t\t\t\tsharedState,\r\n\t\t\t\tgameState,\r\n\t\t\t\tspectator,\r\n\t\t\t);\r\n\t\t}\r\n\t\tattackerForStart = (attackerForStart + 1) % 2;\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatQuestRewards = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tcurrentAttacker = handleStartOfCombatQuestRewardsForPlayer(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatQuestRewardsForPlayer(\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatSpells = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tcurrentAttacker = handleStartOfCombatSpellsForPlayer(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatSpellsForPlayer(\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatAnomalies = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tcurrentAttacker = handleStartOfCombatAnomaliesForPlayer(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatAnomaliesForPlayer(\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatQuestRewardsForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (!playerEntity.questRewards?.length) {\r\n\t\treturn currentAttacker;\r\n\t}\r\n\tfor (const reward of playerEntity.questRewards) {\r\n\t\tswitch (reward) {\r\n\t\t\tcase CardIds.EvilTwin:\r\n\t\t\t\tif (!!playerBoard.length && playerBoard.length < 7) {\r\n\t\t\t\t\tconst highestHealthMinion = [...playerBoard].sort((a, b) => b.health - a.health)[0];\r\n\t\t\t\t\tconst copy: BoardEntity = {\r\n\t\t\t\t\t\t...highestHealthMinion,\r\n\t\t\t\t\t\tlastAffectedByEntity: null,\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\t\tcopy.cardId,\r\n\t\t\t\t\t\t1,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\thighestHealthMinion.friendly,\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tcopy,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(highestHealthMinion) + 1);\r\n\t\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\t\tnewMinions,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\thighestHealthMinion,\r\n\t\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, copy, playerBoard, null, null);\r\n\t\t\t\t}\r\n\t\t\t\t// Recompute first attacker\r\n\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=93229c4a-d864-4196-83dd-2fea2a5bf70a&turn=29&action=0\r\n\t\t\t\treturn playerBoard.length > opponentBoard.length\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: Math.round(Math.random());\r\n\t\t\tcase CardIds.StaffOfOrigination_BG24_Reward_312:\r\n\t\t\t\tplayerBoard.forEach((entity) => {\r\n\t\t\t\t\tmodifyAttack(entity, 15, playerBoard, allCards);\r\n\t\t\t\t\tmodifyHealth(entity, 15, playerBoard, allCards);\r\n\t\t\t\t\tafterStatsUpdate(entity, playerBoard, allCards);\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, entity, playerBoard, null, null);\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.StolenGold:\r\n\t\t\t\tif (playerBoard.length > 0) {\r\n\t\t\t\t\tmakeMinionGolden(\r\n\t\t\t\t\t\tplayerBoard[0],\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\tif (playerBoard.length > 1) {\r\n\t\t\t\t\tmakeMinionGolden(\r\n\t\t\t\t\t\tplayerBoard[playerBoard.length - 1],\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatSpellsForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (!playerEntity.secrets?.length) {\r\n\t\treturn currentAttacker;\r\n\t}\r\n\tfor (const secret of playerEntity.secrets) {\r\n\t\tswitch (secret.cardId) {\r\n\t\t\tcase CardIds.UpperHand_BG28_573:\r\n\t\t\t\tif (!!opponentBoard.length) {\r\n\t\t\t\t\tconst target = pickRandom(opponentBoard);\r\n\t\t\t\t\ttarget.health = 1;\r\n\t\t\t\t\ttarget.maxHealth = 1;\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, target, opponentBoard, null, null);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatAnomaliesForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (!gameState.anomalies?.length) {\r\n\t\treturn currentAttacker;\r\n\t}\r\n\tfor (const anomaly of gameState.anomalies) {\r\n\t\tswitch (anomaly) {\r\n\t\t\tcase CardIds.BlessedOrBlighted_BG27_Anomaly_726:\r\n\t\t\t\tif (playerBoard.length > 0) {\r\n\t\t\t\t\tconst dsTarget = playerBoard[0];\r\n\t\t\t\t\tupdateDivineShield(dsTarget, playerBoard, true, allCards);\r\n\t\t\t\t\tconst rebornTarget = playerBoard[playerBoard.length - 1];\r\n\t\t\t\t\trebornTarget.reborn = true;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.AnomalousTwin_BG27_Anomaly_560:\r\n\t\t\t\tif (!!playerBoard.length && playerBoard.length < 7) {\r\n\t\t\t\t\tconst highestHealthMinion = [...playerBoard].sort((a, b) => b.health - a.health)[0];\r\n\t\t\t\t\tconst copy: BoardEntity = {\r\n\t\t\t\t\t\t...highestHealthMinion,\r\n\t\t\t\t\t\tlastAffectedByEntity: null,\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\t\tcopy.cardId,\r\n\t\t\t\t\t\t1,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\thighestHealthMinion.friendly,\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tcopy,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(highestHealthMinion) + 1);\r\n\t\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\t\tnewMinions,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\thighestHealthMinion,\r\n\t\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, copy, playerBoard, null, null);\r\n\t\t\t\t}\r\n\t\t\t\t// Recompute first attacker\r\n\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=93229c4a-d864-4196-83dd-2fea2a5bf70a&turn=29&action=0\r\n\t\t\t\treturn playerBoard.length > opponentBoard.length\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: Math.round(Math.random());\r\n\t\t}\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nexport const handleStartOfCombatHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// Apparently it's a toin coss about whether to handle Illidan first or Al'Akir first\r\n\t// Auras are only relevant for Illidan, and already applied there\r\n\tif (Math.random() < 0.5) {\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else {\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handlePlayerIllidanHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tconst playerHeroPowerId = playerEntity.heroPowerId || getHeroPowerForHero(playerEntity.cardId);\r\n\tif (playerHeroPowerId === CardIds.Wingmen && playerBoard.length > 0) {\r\n\t\thandleIllidanForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = (currentAttacker + 1) % 2;\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\n// TODO: not exactly correct, because of \"attack immediately\", but it's close enough\r\nconst handleIllidanForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// Otherwise, if the first minion dies on the attack, and the board has only 2 minions, we\r\n\t// miss the second one\r\n\tconst minionsAtStart = playerBoard.length;\r\n\tconst firstAttacker = playerBoard[0];\r\n\tconst secondAttacker = minionsAtStart > 1 ? playerBoard[playerBoard.length - 1] : null;\r\n\r\n\tmodifyAttack(firstAttacker, 2, playerBoard, allCards);\r\n\tmodifyHealth(firstAttacker, 1, playerBoard, allCards);\r\n\tafterStatsUpdate(firstAttacker, playerBoard, allCards);\r\n\tspectator.registerPowerTarget(firstAttacker, firstAttacker, playerBoard, playerEntity, opponentEntity);\r\n\tsimulateAttack(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tundefined,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t\t0,\r\n\t);\r\n\r\n\tif (!!secondAttacker && !secondAttacker.definitelyDead && secondAttacker.health > 0) {\r\n\t\tmodifyAttack(secondAttacker, 2, playerBoard, allCards);\r\n\t\tmodifyHealth(secondAttacker, 1, playerBoard, allCards);\r\n\t\tafterStatsUpdate(secondAttacker, playerBoard, allCards);\r\n\t\tspectator.registerPowerTarget(secondAttacker, secondAttacker, playerBoard, playerEntity, opponentEntity);\r\n\t\tsimulateAttack(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tundefined,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t\tplayerBoard.length - 1,\r\n\t\t);\r\n\t}\r\n};\r\n\r\nconst handleAlakirForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tconst firstEntity = playerBoard[0];\r\n\tfirstEntity.windfury = true;\r\n\tif (!firstEntity.divineShield) {\r\n\t\tupdateDivineShield(firstEntity, playerBoard, true, allCards);\r\n\t}\r\n\tfirstEntity.taunt = true;\r\n\tspectator.registerPowerTarget(firstEntity, firstEntity, playerBoard, playerEntity, opponentEntity);\r\n};\r\n\r\nconst handleTamsinForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tconst chosenEntity = pickRandomLowestHealth(playerBoard);\r\n\tif (!chosenEntity) {\r\n\t\tconsole.warn('could not pick any entity for tamsin');\r\n\t\treturn;\r\n\t}\r\n\tconst newBoard = playerBoard.filter((e) => e.entityId !== chosenEntity.entityId);\r\n\t// How to mark the minion as dead\r\n\tchosenEntity.definitelyDead = true;\r\n\tnewBoard.forEach((e) => {\r\n\t\tmodifyAttack(e, chosenEntity.attack, newBoard, allCards);\r\n\t\tmodifyHealth(e, chosenEntity.health, newBoard, allCards);\r\n\t\tafterStatsUpdate(e, newBoard, allCards);\r\n\t\tspectator.registerPowerTarget(chosenEntity, e, newBoard, playerEntity, opponentEntity);\r\n\t});\r\n};\r\n\r\nconst handleTeronForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// The board state is snapshot after the minion dies\r\n\tconst deadMinionEntityId = playerEntity.heroPowerInfo;\r\n\tconst minionThatWillDie = playerBoard.find((e) => e.entityId === deadMinionEntityId);\r\n\tif (minionThatWillDie) {\r\n\t\tconst minionIndexFromRight = playerBoard.length - 1 - playerBoard.indexOf(minionThatWillDie);\r\n\t\tplayerEntity.rapidReanimationIndexFromRight = minionIndexFromRight;\r\n\t\tconst minionToCopy = {\r\n\t\t\t...minionThatWillDie,\r\n\t\t\tenchantments: minionThatWillDie.enchantments.map((e) => ({ ...e })) ?? [],\r\n\t\t} as BoardEntity;\r\n\t\tremoveAurasFromSelf(minionToCopy, playerBoard, playerEntity, allCards, sharedState, spectator);\r\n\t\tplayerEntity.rapidReanimationMinion = minionToCopy;\r\n\t\tminionThatWillDie.definitelyDead = true;\r\n\t\tspectator.registerPowerTarget(playerEntity, minionThatWillDie, playerBoard, playerEntity, opponentEntity);\r\n\t}\r\n};\r\n\r\nconst handleWaxWarbandForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tif (playerBoard.length > 0) {\r\n\t\tconst boardWithTribes = playerBoard.filter((e) => !!allCards.getCard(e.cardId)?.races?.length);\r\n\t\tconst boardWithoutAll = boardWithTribes.filter(\r\n\t\t\t(e) => !allCards.getCard(e.cardId).races.includes(Race[Race.ALL]),\r\n\t\t);\r\n\t\tconst selectedMinions = selectMinions(boardWithoutAll, ALL_BG_RACES, allCards);\r\n\t\tconst allMinions = [\r\n\t\t\t...selectedMinions,\r\n\t\t\t...boardWithTribes.filter((e) => allCards.getCard(e.cardId).races.includes(Race[Race.ALL])),\r\n\t\t];\r\n\t\tallMinions.forEach((e) => {\r\n\t\t\tmodifyAttack(e, cardsData.getTavernLevel(e.cardId), playerBoard, allCards);\r\n\t\t\tmodifyHealth(e, cardsData.getTavernLevel(e.cardId), playerBoard, allCards);\r\n\t\t\tafterStatsUpdate(e, playerBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(playerEntity, e, playerBoard, playerEntity, opponentEntity);\r\n\t\t});\r\n\t}\r\n};\r\n\r\n// Not perfect, as I don't think this solves the issue where some cards are mutually exclusive\r\nconst selectMinions = (minions: BoardEntity[], tribes: Race[], allCards: AllCardsService): BoardEntity[] => {\r\n\t// Step 1\r\n\tconst minionsByTribe: { [tribe: string]: BoardEntity[] } = {};\r\n\tfor (const minion of minions) {\r\n\t\tfor (const tribe of allCards.getCard(minion.cardId).races) {\r\n\t\t\tif (!minionsByTribe[tribe]) {\r\n\t\t\t\tminionsByTribe[tribe] = [];\r\n\t\t\t}\r\n\t\t\tminionsByTribe[tribe].push(minion);\r\n\t\t}\r\n\t}\r\n\tfor (const tribe of ALL_BG_RACES) {\r\n\t\tminionsByTribe[tribe] = shuffleArray(minionsByTribe[Race[tribe]] ?? []);\r\n\t}\r\n\r\n\tconst selectedMinions: BoardEntity[] = [];\r\n\r\n\t// Step 3\r\n\tfor (const tribe of tribes) {\r\n\t\tif (minionsByTribe[tribe]) {\r\n\t\t\tminionsByTribe[tribe].sort(\r\n\t\t\t\t(a, b) => allCards.getCard(a.cardId).races.length - allCards.getCard(b.cardId).races.length,\r\n\t\t\t);\r\n\t\t\tfor (const minion of minionsByTribe[tribe]) {\r\n\t\t\t\tif (!selectedMinions.includes(minion)) {\r\n\t\t\t\t\tselectedMinions.push(minion);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Step 4\r\n\treturn selectedMinions;\r\n};\r\n\r\nconst handleOzumatForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// Because of some interactions between start of combat hero powers, it can happen that Ozumat is already present\r\n\t// on the board when we receive the board state\r\n\tif (\r\n\t\tplayerBoard.length < 7 &&\r\n\t\t!playerBoard.some((e) => e.cardId === CardIds.Tentacular_OzumatsTentacleToken_BG23_HERO_201pt)\r\n\t) {\r\n\t\tconst tentacularSize = playerEntity.heroPowerInfo;\r\n\t\tconst tentacular = spawnEntities(\r\n\t\t\tCardIds.Tentacular_OzumatsTentacleToken_BG23_HERO_201pt,\r\n\t\t\t1,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t\tfriendly,\r\n\t\t\ttrue,\r\n\t\t\tfalse,\r\n\t\t\tfalse,\r\n\t\t);\r\n\t\ttentacular[0].attack = tentacularSize;\r\n\t\ttentacular[0].health = tentacularSize;\r\n\t\tconst indexFromRight = 0;\r\n\t\tperformEntitySpawns(\r\n\t\t\ttentacular,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tspectator.registerPowerTarget(playerEntity, tentacular[0], playerBoard, playerEntity, opponentEntity);\r\n\t}\r\n};\r\n\r\nconst handlePlayerStartOfCombatHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// eslint-disable-next-line prefer-const\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\tconst playerHeroPowerId = playerEntity.heroPowerId || getHeroPowerForHero(playerEntity.cardId);\r\n\t// TODO: should this recompute the first attack order?\r\n\tif (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimLeftToken) {\r\n\t\tconst target = opponentBoard[0];\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimRightToken) {\r\n\t\tconst target = opponentBoard[opponentBoard.length - 1];\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimLowToken) {\r\n\t\tconst smallestHealthMinion = [...opponentBoard].sort((a, b) => a.health - b.health)[0];\r\n\t\tconst target = pickRandom(opponentBoard.filter((e) => e.health === smallestHealthMinion.health));\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimHighToken) {\r\n\t\tconst highestHealthMinion = [...opponentBoard].sort((a, b) => b.health - a.health)[0];\r\n\t\tconst target = pickRandom(opponentBoard.filter((e) => e.health === highestHealthMinion.health));\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t}\r\n\tprocessMinionDeath(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n\tif (shouldRecomputeCurrentAttacker) {\r\n\t\tconst previousCurrentAttacker = currentAttacker;\r\n\t\tcurrentAttacker =\r\n\t\t\tplayerBoard.length > opponentBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: 1\r\n\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: 0\r\n\t\t\t\t: currentAttacker;\r\n\t\t// console.debug(\r\n\t\t// \t'recompting current attacker',\r\n\t\t// \tcurrentAttacker,\r\n\t\t// \tplayerBoard.length,\r\n\t\t// \topponentBoard.length,\r\n\t\t// \tpreviousCurrentAttacker,\r\n\t\t// \tstringifySimple(playerBoard, allCards),\r\n\t\t// \tstringifySimple(opponentBoard, allCards),\r\n\t\t// );\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nexport const getHeroPowerForHero = (heroCardId: string): string => {\r\n\tswitch (heroCardId) {\r\n\t\tcase CardIds.IllidanStormrage_TB_BaconShop_HERO_08:\r\n\t\t\treturn CardIds.Wingmen;\r\n\t\tcase CardIds.TheLichKing_TB_BaconShop_HERO_22:\r\n\t\t\treturn CardIds.RebornRites;\r\n\t\tcase CardIds.ProfessorPutricide_BG25_HERO_100:\r\n\t\t\treturn CardIds.RagePotion;\r\n\t\tcase CardIds.Deathwing_TB_BaconShop_HERO_52:\r\n\t\t\treturn CardIds.AllWillBurn;\r\n\t\tcase CardIds.TeronGorefiend_BG25_HERO_103:\r\n\t\t\treturn CardIds.TeronGorefiend_RapidReanimation;\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const performStartOfCombatMinionsForPlayer = (\r\n\tattacker: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\t// Apparently, the board composition used for start of combat minion effects (like Red Whelp, and I assume it works the\r\n\t// same way for others like Prized Promo Drake or Mantid Queen) is the one that is used before Illidan's effect is handled.\r\n\t// Since this also runs before HP start of combat, we probably also use the state as it was before HP were triggered, like\r\n\t// Tamsin's Phylactery.\r\n\tattackingBoardBefore: BoardEntity[],\r\n\tdefendingBoardBefore: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// Don't forget to update START_OF_COMBAT_CARD_IDS\r\n\tif (attacker.cardId === CardIds.RedWhelp_BGS_019) {\r\n\t\tconst damage = attackingBoardBefore\r\n\t\t\t.map((entity) => allCards.getCard(entity.cardId).races)\r\n\t\t\t.filter((races) => isCorrectTribe(races, Race.DRAGON)).length;\r\n\t\tdealDamageToRandomEnemy(\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattacker,\r\n\t\t\tdamage,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (attacker.cardId === CardIds.RedWhelp_TB_BaconUps_102) {\r\n\t\tconst damage = attackingBoardBefore\r\n\t\t\t.map((entity) => allCards.getCard(entity.cardId).races)\r\n\t\t\t.filter((races) => isCorrectTribe(races, Race.DRAGON)).length;\r\n\t\tdealDamageToRandomEnemy(\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattacker,\r\n\t\t\tdamage,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tdealDamageToRandomEnemy(\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattacker,\r\n\t\t\tdamage,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.PrizedPromoDrake_BG21_014 ||\r\n\t\tattacker.cardId === CardIds.PrizedPromoDrake_BG21_014_G\r\n\t) {\r\n\t\tconst numberOfDragons = attackingBoardBefore\r\n\t\t\t.map((entity) => allCards.getCard(entity.cardId).races)\r\n\t\t\t.filter((races) => isCorrectTribe(races, Race.DRAGON)).length;\r\n\t\tconst neighbours = getNeighbours(attackingBoard, attacker);\r\n\t\tconst multiplier = attacker.cardId === CardIds.PrizedPromoDrake_BG21_014_G ? 2 : 1;\r\n\t\tneighbours.forEach((entity) => {\r\n\t\t\tmodifyAttack(entity, multiplier * numberOfDragons, attackingBoard, allCards);\r\n\t\t\tmodifyHealth(entity, multiplier * numberOfDragons, attackingBoard, allCards);\r\n\t\t\tafterStatsUpdate(entity, attackingBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(attacker, entity, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t});\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.ChoralMrrrglr_BG26_354 ||\r\n\t\tattacker.cardId === CardIds.ChoralMrrrglr_BG26_354_G\r\n\t) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.ChoralMrrrglr_BG26_354_G ? 2 : 1;\r\n\t\tmodifyAttack(attacker, multiplier * attackingBoardHero.globalInfo?.ChoralAttackBuff, attackingBoard, allCards);\r\n\t\tmodifyHealth(attacker, multiplier * attackingBoardHero.globalInfo?.ChoralHealthBuff, attackingBoard, allCards);\r\n\t\tafterStatsUpdate(attacker, attackingBoard, allCards);\r\n\t\tspectator.registerPowerTarget(attacker, attacker, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.AmberGuardian_BG24_500 ||\r\n\t\tattacker.cardId === CardIds.AmberGuardian_BG24_500_G\r\n\t) {\r\n\t\t// First try to get a target without divine shield, and if none is available, pick one with divine shield\r\n\t\tconst otherDragons = attackingBoard\r\n\t\t\t.filter((e) => hasCorrectTribe(e, Race.DRAGON, allCards))\r\n\t\t\t.filter((e) => e.entityId !== attacker.entityId);\r\n\t\tconst loops = attacker.cardId === CardIds.AmberGuardian_BG24_500_G ? 2 : 1;\r\n\t\tconst dragonsToConsider = otherDragons;\r\n\t\tfor (let i = 0; i < loops; i++) {\r\n\t\t\tconst otherDragon =\r\n\t\t\t\tpickRandom(dragonsToConsider.filter((e) => !e.divineShield)) ?? pickRandom(dragonsToConsider);\r\n\t\t\tif (otherDragon) {\r\n\t\t\t\tif (!otherDragon.divineShield) {\r\n\t\t\t\t\tupdateDivineShield(otherDragon, attackingBoard, true, allCards);\r\n\t\t\t\t}\r\n\t\t\t\tmodifyAttack(otherDragon, 2, attackingBoard, allCards);\r\n\t\t\t\tmodifyHealth(otherDragon, 2, attackingBoard, allCards);\r\n\t\t\t\tafterStatsUpdate(otherDragon, attackingBoard, allCards);\r\n\t\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\totherDragon,\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\tdragonsToConsider.splice(dragonsToConsider.indexOf(otherDragon), 1);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.SanctumRester_BG26_356 ||\r\n\t\tattacker.cardId === CardIds.SanctumRester_BG26_356_G\r\n\t) {\r\n\t\tconst buff = attacker.cardId === CardIds.SanctumRester_BG26_356_G ? 16 : 8;\r\n\t\t// First try to get a target without divine shield, and if none is available, pick one with divine shield\r\n\t\tconst otherDragons = attackingBoard\r\n\t\t\t.filter((e) => hasCorrectTribe(e, Race.DRAGON, allCards))\r\n\t\t\t.filter((e) => e.entityId !== attacker.entityId);\r\n\t\totherDragons.forEach((otherDragon) => {\r\n\t\t\tmodifyHealth(otherDragon, buff, attackingBoard, allCards);\r\n\t\t\tafterStatsUpdate(otherDragon, attackingBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\tattacker,\r\n\t\t\t\totherDragon,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t);\r\n\t\t});\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.Soulsplitter_BG25_023 ||\r\n\t\tattacker.cardId === CardIds.Soulsplitter_BG25_023_G\r\n\t) {\r\n\t\tconst numberOfTargets = attacker.cardId === CardIds.Soulsplitter_BG25_023_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfTargets; i++) {\r\n\t\t\tconst undeadsWithoutReborn = attackingBoard\r\n\t\t\t\t.filter((e) => hasCorrectTribe(e, Race.UNDEAD, allCards))\r\n\t\t\t\t.filter((e) => !e.reborn);\r\n\t\t\tconst chosenUndead = pickRandom(undeadsWithoutReborn);\r\n\t\t\tif (chosenUndead) {\r\n\t\t\t\tchosenUndead.reborn = true;\r\n\t\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tchosenUndead,\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}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.Crabby_BG22_HERO_000_Buddy ||\r\n\t\tattacker.cardId === CardIds.Crabby_BG22_HERO_000_Buddy_G\r\n\t) {\r\n\t\tconst neighbours = getNeighbours(attackingBoard, attacker);\r\n\t\tconst multiplier = attacker.cardId === CardIds.Crabby_BG22_HERO_000_Buddy_G ? 2 : 1;\r\n\t\tneighbours.forEach((entity) => {\r\n\t\t\tmodifyAttack(entity, multiplier * (attackingBoardHero.deadEyeDamageDone ?? 0), attackingBoard, allCards);\r\n\t\t\tmodifyHealth(entity, multiplier * (attackingBoardHero.deadEyeDamageDone ?? 0), attackingBoard, allCards);\r\n\t\t\tafterStatsUpdate(entity, attackingBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(attacker, entity, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t});\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.CorruptedMyrmidon_BG23_012 ||\r\n\t\tattacker.cardId === CardIds.CorruptedMyrmidon_BG23_012_G\r\n\t) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.CorruptedMyrmidon_BG23_012_G ? 2 : 1;\r\n\t\tmodifyAttack(attacker, multiplier * attacker.attack, attackingBoard, allCards);\r\n\t\tmodifyHealth(attacker, multiplier * attacker.health, attackingBoard, allCards);\r\n\t\tafterStatsUpdate(attacker, attackingBoard, allCards);\r\n\t\tspectator.registerPowerTarget(attacker, attacker, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.InterrogatorWhitemane_BG24_704 ||\r\n\t\tattacker.cardId === CardIds.InterrogatorWhitemane_BG24_704_G\r\n\t) {\r\n\t\tif (defendingBoard.length > 0) {\r\n\t\t\tconst attackerIndex = attackingBoard.indexOf(attacker);\r\n\t\t\tconst defenderPosition = attackerIndex - (attackingBoard.length - defendingBoard.length) / 2;\r\n\t\t\tif (Math.round(defenderPosition) === defenderPosition) {\r\n\t\t\t\tcastImpure(defendingBoard[defenderPosition], attacker, attackingBoard, spectator);\r\n\t\t\t} else {\r\n\t\t\t\tcastImpure(defendingBoard[defenderPosition - 0.5], attacker, attackingBoard, spectator);\r\n\t\t\t\tcastImpure(defendingBoard[defenderPosition + 0.5], attacker, attackingBoard, spectator);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (attacker.cardId === CardIds.MantidQueen_BG22_402 || attacker.cardId === CardIds.MantidQueen_BG22_402_G) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.MantidQueen_BG22_402_G ? 2 : 1;\r\n\t\tconst allRaces = attackingBoardBefore\r\n\t\t\t.map((entity) => entity.cardId)\r\n\t\t\t.flatMap((cardId) => allCards.getCard(cardId).races)\r\n\t\t\t.filter((race) => !!race && race !== Race[Race.BLANK]);\r\n\t\tconst totalRaces =\r\n\t\t\t[...new Set(allRaces.filter((race) => race !== Race[Race.ALL]))].length +\r\n\t\t\tallRaces.filter((race) => race === Race[Race.ALL]).length;\r\n\t\tfor (let i = 0; i < multiplier; i++) {\r\n\t\t\tfor (let j = 0; j < totalRaces; j++) {\r\n\t\t\t\tconst buffType = getRandomMantidQueenBuffType(attacker);\r\n\t\t\t\tswitch (buffType) {\r\n\t\t\t\t\tcase 'stats':\r\n\t\t\t\t\t\tmodifyAttack(attacker, 5, attackingBoard, allCards);\r\n\t\t\t\t\t\tmodifyHealth(attacker, 5, attackingBoard, allCards);\r\n\t\t\t\t\t\tafterStatsUpdate(attacker, attackingBoard, allCards);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'reborn':\r\n\t\t\t\t\t\tattacker.reborn = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'taunt':\r\n\t\t\t\t\t\tattacker.taunt = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'windfury':\r\n\t\t\t\t\t\tattacker.windfury = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tattacker,\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}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.CarbonicCopy_BG27_503 ||\r\n\t\tattacker.cardId === CardIds.CarbonicCopy_BG27_503_G\r\n\t) {\r\n\t\tconst numberOfCopies = attacker.cardId === CardIds.CarbonicCopy_BG27_503_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfCopies; i++) {\r\n\t\t\tif (!!attackingBoard.length && attackingBoard.length < 7) {\r\n\t\t\t\tconst copy: BoardEntity = {\r\n\t\t\t\t\t...attacker,\r\n\t\t\t\t\tlastAffectedByEntity: null,\r\n\t\t\t\t};\r\n\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\tcopy.cardId,\r\n\t\t\t\t\t1,\r\n\t\t\t\t\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\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t\tattacker.friendly,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tcopy,\r\n\t\t\t\t);\r\n\t\t\t\tconst indexFromRight = attackingBoard.length - (attackingBoard.indexOf(attacker) + 1);\r\n\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\tnewMinions,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t\tspectator.registerPowerTarget(attacker, copy, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.DiremuckForager_BG27_556 ||\r\n\t\tattacker.cardId === CardIds.DiremuckForager_BG27_556_G\r\n\t) {\r\n\t\tconst potentialTargets = attackingBoardHero.hand.filter((e) => !!e.cardId).filter((e) => !e.locked);\r\n\t\tif (potentialTargets.length > 0) {\r\n\t\t\tconst target = pickRandom(potentialTargets);\r\n\t\t\t// When it's the opponent, the game state already contains all the buffs\r\n\t\t\tif (target?.friendly) {\r\n\t\t\t\tconst diremuckBuff = attacker.cardId === CardIds.DiremuckForager_BG27_556_G ? 4 : 2;\r\n\t\t\t\tmodifyAttack(target, diremuckBuff, attackingBoard, allCards);\r\n\t\t\t\tmodifyHealth(target, diremuckBuff, attackingBoard, allCards);\r\n\t\t\t\tafterStatsUpdate(target, attackingBoard, allCards);\r\n\t\t\t\tspectator.registerPowerTarget(attacker, target, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t\t}\r\n\t\t\tif (attackingBoard.length < 7) {\r\n\t\t\t\ttarget.locked = true;\r\n\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\ttarget.cardId,\r\n\t\t\t\t\t1,\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\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t\tattacker.friendly,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\t{ ...target } as BoardEntity,\r\n\t\t\t\t);\r\n\t\t\t\tfor (const s of newMinions) {\r\n\t\t\t\t\ts.onCanceledSummon = () => (target.locked = false);\r\n\t\t\t\t}\r\n\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\tnewMinions,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tattackingBoard.length - (attackingBoard.indexOf(attacker) + 1),\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.HawkstriderHerald_BG27_079 ||\r\n\t\tattacker.cardId === CardIds.HawkstriderHerald_BG27_079_G\r\n\t) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.HawkstriderHerald_BG27_079_G ? 2 : 1;\r\n\t\tfor (const entity of attackingBoard) {\r\n\t\t\tfor (let i = 0; i < multiplier; i++) {\r\n\t\t\t\tspectator.registerPowerTarget(attacker, entity, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t\t\thandleDeathrattles(\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tentity,\r\n\t\t\t\t\tattackingBoard.length - 1 - attackingBoard.indexOf(entity),\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t[],\r\n\t\t\t\t\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.AudaciousAnchor_BG28_904 ||\r\n\t\tattacker.cardId === CardIds.AudaciousAnchor_BG28_904_G\r\n\t) {\r\n\t\tconst iterations = attacker.cardId === CardIds.AudaciousAnchor_BG28_904_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < iterations; i++) {\r\n\t\t\tconst targets = findNearestEnemies(\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattacker,\r\n\t\t\t\tattackingBoard.length - 1 - attackingBoard.indexOf(attacker),\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\t1,\r\n\t\t\t\tallCards,\r\n\t\t\t);\r\n\t\t\tif (!targets.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tconst target = targets[0];\r\n\t\t\tlet battleAttacker = attacker;\r\n\t\t\tlet battleDefender = target;\r\n\t\t\twhile (\r\n\t\t\t\tbattleAttacker.health > 0 &&\r\n\t\t\t\tbattleDefender.health > 0 &&\r\n\t\t\t\t!battleAttacker.definitelyDead &&\r\n\t\t\t\t!battleDefender.definitelyDead\r\n\t\t\t) {\r\n\t\t\t\tdoFullAttack(\r\n\t\t\t\t\tbattleAttacker,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tbattleDefender,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t\tbattleAttacker = target;\r\n\t\t\t\tbattleDefender = attacker;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tprocessMinionDeath(\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n};\r\n\r\nconst applyAllWillBurn = (\r\n\tboard1: BoardEntity[],\r\n\tboard2: BoardEntity[],\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tallCards: AllCardsService,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tfor (const entity of board1) {\r\n\t\tmodifyAttack(entity, 2, board1, allCards);\r\n\t\tafterStatsUpdate(entity, board1, allCards);\r\n\t\tspectator.registerPowerTarget(sourceEntity, entity, board1, null, null);\r\n\t}\r\n\tfor (const entity of board2) {\r\n\t\tmodifyAttack(entity, 2, board2, allCards);\r\n\t\tafterStatsUpdate(entity, board2, allCards);\r\n\t\tspectator.registerPowerTarget(sourceEntity, entity, board2, null, null);\r\n\t}\r\n};\r\n\r\nconst castImpure = (entity: BoardEntity, source: BoardEntity, board: BoardEntity[], spectator: Spectator) => {\r\n\tif (!entity) {\r\n\t\treturn;\r\n\t}\r\n\tconst multiplier = source.cardId === CardIds.InterrogatorWhitemane_BG24_704_G ? 3 : 2;\r\n\tentity.taunt = true;\r\n\tentity.damageMultiplier = entity.damageMultiplier ?? 1;\r\n\tentity.damageMultiplier *= multiplier;\r\n\tspectator.registerPowerTarget(source, entity, board, null, null);\r\n};\r\n\r\nconst getRandomMantidQueenBuffType = (entity: BoardEntity): 'stats' | 'reborn' | 'windfury' | 'taunt' => {\r\n\tconst possibilities: ('stats' | 'reborn' | 'windfury' | 'taunt')[] = ['stats'];\r\n\tif (!entity.reborn) {\r\n\t\tpossibilities.push('reborn');\r\n\t}\r\n\tif (!entity.windfury) {\r\n\t\tpossibilities.push('windfury');\r\n\t}\r\n\tif (!entity.taunt) {\r\n\t\tpossibilities.push('taunt');\r\n\t}\r\n\treturn pickRandom(possibilities);\r\n};\r\n"]}
1
+ {"version":3,"file":"start-of-combat.js","sourceRoot":"","sources":["../../src/simulation/start-of-combat.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { ALL_BG_RACES, AllCardsService, CardIds, Race } from '@firestone-hs/reference-data';\r\nimport { BgsGameState } from '../bgs-battle-info';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { CardsData, START_OF_COMBAT_CARD_IDS } from '../cards/cards-data';\r\nimport { pickRandom, pickRandomLowestHealth, shuffleArray } from '../services/utils';\r\nimport {\r\n\tafterStatsUpdate,\r\n\thasCorrectTribe,\r\n\tisCorrectTribe,\r\n\tmakeMinionGolden,\r\n\tmodifyAttack,\r\n\tmodifyHealth,\r\n\tupdateDivineShield,\r\n} from '../utils';\r\nimport { removeAurasFromSelf } from './add-minion-to-board';\r\nimport {\r\n\tdealDamageToEnemy,\r\n\tdealDamageToRandomEnemy,\r\n\tdoFullAttack,\r\n\tfindNearestEnemies,\r\n\tgetNeighbours,\r\n\tperformEntitySpawns,\r\n\tprocessMinionDeath,\r\n\tsimulateAttack,\r\n} from './attack';\r\nimport {\r\n\tapplyEarthInvocationEnchantment,\r\n\tapplyFireInvocationEnchantment,\r\n\tapplyLightningInvocationEnchantment,\r\n\tapplyWaterInvocationEnchantment,\r\n\thandleDeathrattles,\r\n} from './deathrattle-effects';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { SharedState } from './shared-state';\r\nimport { Spectator } from './spectator/spectator';\r\n\r\nexport const handleStartOfCombat = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// https://twitter.com/DCalkosz/status/1564705111850434561\r\n\tcurrentAttacker = handleStartOfCombatQuestRewards(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatSpells(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatAnomalies(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\t// https://twitter.com/DCalkosz/status/1488361384320528388?s=20&t=1ECxRZFdjqwEa2fRsXk32Q\r\n\t// There’s a certain order for Start of Combat hero powers, rather than “coin flips” where\r\n\t// an unlucky trigger order could mess up some positioning you had planned for your own hero\r\n\t// power. “Precombat” (Al’Akir, Y’Shaarj), then Illidan, then others.\r\n\t// Update: this seems to have changed: https://x.com/LoewenMitchell/status/1737588920139825335?s=20\r\n\t// now you have all hero powers trigger in a first phase, then you have Illidan, and once everything has triggered, you have Tavish\r\n\tcurrentAttacker = handlePreCombatHeroPowers(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\t// Because start of combat powers like Red Whelp's use the board composition before Illidan's strike to know the amount of damage\r\n\tconst playerBoardBefore = playerBoard.map((e) => ({ ...e }));\r\n\tconst opponentBoardBefore = opponentBoard.map((e) => ({ ...e }));\r\n\tcurrentAttacker = handleIllidanHeroPowers(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatHeroPowers(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatMinions(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tplayerBoardBefore,\r\n\t\topponentBoardBefore,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handlePreCombatHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (Math.random() < 0.5) {\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else {\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePreCombatHeroPowersForPlayer(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tgameState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handlePreCombatHeroPowersForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\t// Some are part of the incoming board: Y'Shaarj, Lich King, Ozumat\r\n\t// Since the order is not important here, we just always do the player first\r\n\tconst playerHeroPowerId = playerEntity.heroPowerId || getHeroPowerForHero(playerEntity.cardId);\r\n\tif (playerHeroPowerId === CardIds.SwattingInsects && playerBoard.length > 0) {\r\n\t\t// Should be sent by the app, but it is an idempotent operation, so we can just reapply it here\r\n\t\thandleAlakirForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.EarthInvocationToken) {\r\n\t\tapplyEarthInvocationEnchantment(playerBoard, null, playerEntity, allCards, sharedState, spectator);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.WaterInvocationToken) {\r\n\t\tapplyWaterInvocationEnchantment(playerBoard, null, playerEntity, allCards, spectator);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.FireInvocationToken) {\r\n\t\tapplyFireInvocationEnchantment(playerBoard, null, playerEntity, allCards, spectator);\r\n\t} else if (playerHeroPowerId === CardIds.AllWillBurn) {\r\n\t\tapplyAllWillBurn(playerBoard, opponentBoard, playerEntity, allCards, spectator);\r\n\t} else if (playerHeroPowerId === CardIds.Ozumat_Tentacular) {\r\n\t\thandleOzumatForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tfriendly,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.TamsinRoame_FragrantPhylactery) {\r\n\t\thandleTamsinForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// Tamsin's hero power somehow happens before the current attacker is chosen.\r\n\t\t// See http://replays.firestoneapp.com/?reviewId=bce94e6b-c807-48e4-9c72-2c5c04421213&turn=6&action=9\r\n\t\t// Even worse: if a scallywag token pops, it attacks before the first attacker is recomputed\r\n\t\tshouldRecomputeCurrentAttacker = true;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.TeronGorefiend_RapidReanimation) {\r\n\t\thandleTeronForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// Same as Tamsin? No, because the new minion should repop automatically\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.WaxWarband) {\r\n\t\thandleWaxWarbandForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.LightningInvocationToken) {\r\n\t\tapplyLightningInvocationEnchantment(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tnull,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\r\n\tprocessMinionDeath(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n\tif (shouldRecomputeCurrentAttacker) {\r\n\t\tconst previousCurrentAttacker = currentAttacker;\r\n\t\tcurrentAttacker =\r\n\t\t\tplayerBoard.length > opponentBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: 1\r\n\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: 0\r\n\t\t\t\t: currentAttacker;\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nexport const handleIllidanHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// console.log('current attacker before', currentAttacker);\r\n\t// Apparently it's a toin coss about whether to handle Illidan first or Al'Akir first\r\n\t// Auras are only relevant for Illidan, and already applied there\r\n\tif (Math.random() < 0.5) {\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else {\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerIllidanHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\tprocessMinionDeath(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n\t// console.log('current attacker after', currentAttacker);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatMinions = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tplayerBoardBefore: BoardEntity[],\r\n\topponentBoardBefore: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tlet attackerForStart = currentAttacker;\r\n\tconst playerAttackers = playerBoard.filter((entity) => START_OF_COMBAT_CARD_IDS.includes(entity.cardId as CardIds));\r\n\tconst opponentAttackers = opponentBoard.filter((entity) =>\r\n\t\tSTART_OF_COMBAT_CARD_IDS.includes(entity.cardId as CardIds),\r\n\t);\r\n\r\n\twhile (playerAttackers.length > 0 || opponentAttackers.length > 0) {\r\n\t\tif (attackerForStart === 0 && playerAttackers.length > 0) {\r\n\t\t\tconst attacker = playerAttackers.splice(0, 1)[0];\r\n\t\t\tif (attacker.health <= 0 || attacker.definitelyDead) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tperformStartOfCombatMinionsForPlayer(\r\n\t\t\t\tattacker,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tplayerBoardBefore,\r\n\t\t\t\topponentBoardBefore,\r\n\t\t\t\tallCards,\r\n\t\t\t\tspawns,\r\n\t\t\t\tsharedState,\r\n\t\t\t\tgameState,\r\n\t\t\t\tspectator,\r\n\t\t\t);\r\n\t\t} else if (attackerForStart === 1 && opponentAttackers.length > 0) {\r\n\t\t\tconst attacker = opponentAttackers.splice(0, 1)[0];\r\n\t\t\tif (attacker.health <= 0 || attacker.definitelyDead) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tperformStartOfCombatMinionsForPlayer(\r\n\t\t\t\tattacker,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\topponentBoardBefore,\r\n\t\t\t\tplayerBoardBefore,\r\n\t\t\t\tallCards,\r\n\t\t\t\tspawns,\r\n\t\t\t\tsharedState,\r\n\t\t\t\tgameState,\r\n\t\t\t\tspectator,\r\n\t\t\t);\r\n\t\t}\r\n\t\tattackerForStart = (attackerForStart + 1) % 2;\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatQuestRewards = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tcurrentAttacker = handleStartOfCombatQuestRewardsForPlayer(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatQuestRewardsForPlayer(\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatSpells = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tcurrentAttacker = handleStartOfCombatSpellsForPlayer(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatSpellsForPlayer(\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatAnomalies = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tcurrentAttacker = handleStartOfCombatAnomaliesForPlayer(\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\tcurrentAttacker = handleStartOfCombatAnomaliesForPlayer(\r\n\t\topponentEntity,\r\n\t\topponentBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tcurrentAttacker,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tgameState,\r\n\t\tspectator,\r\n\t);\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatQuestRewardsForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (!playerEntity.questRewards?.length) {\r\n\t\treturn currentAttacker;\r\n\t}\r\n\tfor (const reward of playerEntity.questRewards) {\r\n\t\tswitch (reward) {\r\n\t\t\tcase CardIds.EvilTwin:\r\n\t\t\t\tif (!!playerBoard.length && playerBoard.length < 7) {\r\n\t\t\t\t\tconst highestHealthMinion = [...playerBoard].sort((a, b) => b.health - a.health)[0];\r\n\t\t\t\t\tconst copy: BoardEntity = {\r\n\t\t\t\t\t\t...highestHealthMinion,\r\n\t\t\t\t\t\tlastAffectedByEntity: null,\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\t\tcopy.cardId,\r\n\t\t\t\t\t\t1,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\thighestHealthMinion.friendly,\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tcopy,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(highestHealthMinion) + 1);\r\n\t\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\t\tnewMinions,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\thighestHealthMinion,\r\n\t\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, copy, playerBoard, null, null);\r\n\t\t\t\t}\r\n\t\t\t\t// Recompute first attacker\r\n\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=93229c4a-d864-4196-83dd-2fea2a5bf70a&turn=29&action=0\r\n\t\t\t\treturn playerBoard.length > opponentBoard.length\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: Math.round(Math.random());\r\n\t\t\tcase CardIds.StaffOfOrigination_BG24_Reward_312:\r\n\t\t\t\tplayerBoard.forEach((entity) => {\r\n\t\t\t\t\tmodifyAttack(entity, 15, playerBoard, allCards);\r\n\t\t\t\t\tmodifyHealth(entity, 15, playerBoard, allCards);\r\n\t\t\t\t\tafterStatsUpdate(entity, playerBoard, allCards);\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, entity, playerBoard, null, null);\r\n\t\t\t\t});\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.StolenGold:\r\n\t\t\t\tif (playerBoard.length > 0) {\r\n\t\t\t\t\tmakeMinionGolden(\r\n\t\t\t\t\t\tplayerBoard[0],\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\tif (playerBoard.length > 1) {\r\n\t\t\t\t\tmakeMinionGolden(\r\n\t\t\t\t\t\tplayerBoard[playerBoard.length - 1],\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatSpellsForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (!playerEntity.secrets?.length) {\r\n\t\treturn currentAttacker;\r\n\t}\r\n\tfor (const secret of playerEntity.secrets) {\r\n\t\tswitch (secret.cardId) {\r\n\t\t\tcase CardIds.UpperHand_BG28_573:\r\n\t\t\t\tif (!!opponentBoard.length) {\r\n\t\t\t\t\tconst target = pickRandom(opponentBoard);\r\n\t\t\t\t\ttarget.health = 1;\r\n\t\t\t\t\ttarget.maxHealth = 1;\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, target, opponentBoard, null, null);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handleStartOfCombatAnomaliesForPlayer = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tif (!gameState.anomalies?.length) {\r\n\t\treturn currentAttacker;\r\n\t}\r\n\tfor (const anomaly of gameState.anomalies) {\r\n\t\tswitch (anomaly) {\r\n\t\t\tcase CardIds.BlessedOrBlighted_BG27_Anomaly_726:\r\n\t\t\t\tif (playerBoard.length > 0) {\r\n\t\t\t\t\tconst dsTarget = playerBoard[0];\r\n\t\t\t\t\tupdateDivineShield(dsTarget, playerBoard, true, allCards);\r\n\t\t\t\t\tconst rebornTarget = playerBoard[playerBoard.length - 1];\r\n\t\t\t\t\trebornTarget.reborn = true;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase CardIds.AnomalousTwin_BG27_Anomaly_560:\r\n\t\t\t\tif (!!playerBoard.length && playerBoard.length < 7) {\r\n\t\t\t\t\tconst highestHealthMinion = [...playerBoard].sort((a, b) => b.health - a.health)[0];\r\n\t\t\t\t\tconst copy: BoardEntity = {\r\n\t\t\t\t\t\t...highestHealthMinion,\r\n\t\t\t\t\t\tlastAffectedByEntity: null,\r\n\t\t\t\t\t};\r\n\t\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\t\tcopy.cardId,\r\n\t\t\t\t\t\t1,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t\thighestHealthMinion.friendly,\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tfalse,\r\n\t\t\t\t\t\tcopy,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(highestHealthMinion) + 1);\r\n\t\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\t\tnewMinions,\r\n\t\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\t\thighestHealthMinion,\r\n\t\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\t\topponentBoard,\r\n\t\t\t\t\t\topponentEntity,\r\n\t\t\t\t\t\tallCards,\r\n\t\t\t\t\t\tspawns,\r\n\t\t\t\t\t\tsharedState,\r\n\t\t\t\t\t\tspectator,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tspectator.registerPowerTarget(playerEntity, copy, playerBoard, null, null);\r\n\t\t\t\t}\r\n\t\t\t\t// Recompute first attacker\r\n\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=93229c4a-d864-4196-83dd-2fea2a5bf70a&turn=29&action=0\r\n\t\t\t\treturn playerBoard.length > opponentBoard.length\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: Math.round(Math.random());\r\n\t\t}\r\n\t}\r\n\r\n\treturn currentAttacker;\r\n};\r\n\r\nexport const handleStartOfCombatHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// Apparently it's a toin coss about whether to handle Illidan first or Al'Akir first\r\n\t// Auras are only relevant for Illidan, and already applied there\r\n\tif (Math.random() < 0.5) {\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else {\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tfalse,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = handlePlayerStartOfCombatHeroPowers(\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\tcurrentAttacker,\r\n\t\t\ttrue,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nconst handlePlayerIllidanHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\tconst playerHeroPowerId = playerEntity.heroPowerId || getHeroPowerForHero(playerEntity.cardId);\r\n\tif (playerHeroPowerId === CardIds.Wingmen && playerBoard.length > 0) {\r\n\t\thandleIllidanForPlayer(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tcurrentAttacker = (currentAttacker + 1) % 2;\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\n// TODO: not exactly correct, because of \"attack immediately\", but it's close enough\r\nconst handleIllidanForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// Otherwise, if the first minion dies on the attack, and the board has only 2 minions, we\r\n\t// miss the second one\r\n\tconst minionsAtStart = playerBoard.length;\r\n\tconst firstAttacker = playerBoard[0];\r\n\tconst secondAttacker = minionsAtStart > 1 ? playerBoard[playerBoard.length - 1] : null;\r\n\r\n\tmodifyAttack(firstAttacker, 2, playerBoard, allCards);\r\n\tmodifyHealth(firstAttacker, 1, playerBoard, allCards);\r\n\tafterStatsUpdate(firstAttacker, playerBoard, allCards);\r\n\tspectator.registerPowerTarget(firstAttacker, firstAttacker, playerBoard, playerEntity, opponentEntity);\r\n\tsimulateAttack(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tundefined,\r\n\t\tallCards,\r\n\t\tspawns,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t\t0,\r\n\t);\r\n\r\n\tif (!!secondAttacker && !secondAttacker.definitelyDead && secondAttacker.health > 0) {\r\n\t\tmodifyAttack(secondAttacker, 2, playerBoard, allCards);\r\n\t\tmodifyHealth(secondAttacker, 1, playerBoard, allCards);\r\n\t\tafterStatsUpdate(secondAttacker, playerBoard, allCards);\r\n\t\tspectator.registerPowerTarget(secondAttacker, secondAttacker, playerBoard, playerEntity, opponentEntity);\r\n\t\tsimulateAttack(\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tundefined,\r\n\t\t\tallCards,\r\n\t\t\tspawns,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t\tplayerBoard.length - 1,\r\n\t\t);\r\n\t}\r\n};\r\n\r\nconst handleAlakirForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tconst firstEntity = playerBoard[0];\r\n\tfirstEntity.windfury = true;\r\n\tif (!firstEntity.divineShield) {\r\n\t\tupdateDivineShield(firstEntity, playerBoard, true, allCards);\r\n\t}\r\n\tfirstEntity.taunt = true;\r\n\tspectator.registerPowerTarget(firstEntity, firstEntity, playerBoard, playerEntity, opponentEntity);\r\n};\r\n\r\nconst handleTamsinForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tconst chosenEntity = pickRandomLowestHealth(playerBoard);\r\n\tif (!chosenEntity) {\r\n\t\tconsole.warn('could not pick any entity for tamsin');\r\n\t\treturn;\r\n\t}\r\n\tconst newBoard = playerBoard.filter((e) => e.entityId !== chosenEntity.entityId);\r\n\t// How to mark the minion as dead\r\n\tchosenEntity.definitelyDead = true;\r\n\tnewBoard.forEach((e) => {\r\n\t\tmodifyAttack(e, chosenEntity.attack, newBoard, allCards);\r\n\t\tmodifyHealth(e, chosenEntity.health, newBoard, allCards);\r\n\t\tafterStatsUpdate(e, newBoard, allCards);\r\n\t\tspectator.registerPowerTarget(chosenEntity, e, newBoard, playerEntity, opponentEntity);\r\n\t});\r\n};\r\n\r\nconst handleTeronForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tspawns: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// The board state is snapshot after the minion dies\r\n\tconst deadMinionEntityId = playerEntity.heroPowerInfo;\r\n\tconst minionThatWillDie = playerBoard.find((e) => e.entityId === deadMinionEntityId);\r\n\tif (minionThatWillDie) {\r\n\t\tconst minionIndexFromRight = playerBoard.length - 1 - playerBoard.indexOf(minionThatWillDie);\r\n\t\tplayerEntity.rapidReanimationIndexFromRight = minionIndexFromRight;\r\n\t\tconst minionToCopy = {\r\n\t\t\t...minionThatWillDie,\r\n\t\t\tenchantments: minionThatWillDie.enchantments.map((e) => ({ ...e })) ?? [],\r\n\t\t} as BoardEntity;\r\n\t\tremoveAurasFromSelf(minionToCopy, playerBoard, playerEntity, allCards, sharedState, spectator);\r\n\t\tplayerEntity.rapidReanimationMinion = minionToCopy;\r\n\t\tminionThatWillDie.definitelyDead = true;\r\n\t\tspectator.registerPowerTarget(playerEntity, minionThatWillDie, playerBoard, playerEntity, opponentEntity);\r\n\t}\r\n};\r\n\r\nconst handleWaxWarbandForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tif (playerBoard.length > 0) {\r\n\t\tconst boardWithTribes = playerBoard.filter((e) => !!allCards.getCard(e.cardId)?.races?.length);\r\n\t\tconst boardWithoutAll = boardWithTribes.filter(\r\n\t\t\t(e) => !allCards.getCard(e.cardId).races.includes(Race[Race.ALL]),\r\n\t\t);\r\n\t\tconst selectedMinions = selectMinions(boardWithoutAll, ALL_BG_RACES, allCards);\r\n\t\tconst allMinions = [\r\n\t\t\t...selectedMinions,\r\n\t\t\t...boardWithTribes.filter((e) => allCards.getCard(e.cardId).races.includes(Race[Race.ALL])),\r\n\t\t];\r\n\t\tallMinions.forEach((e) => {\r\n\t\t\tmodifyAttack(e, cardsData.getTavernLevel(e.cardId), playerBoard, allCards);\r\n\t\t\tmodifyHealth(e, cardsData.getTavernLevel(e.cardId), playerBoard, allCards);\r\n\t\t\tafterStatsUpdate(e, playerBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(playerEntity, e, playerBoard, playerEntity, opponentEntity);\r\n\t\t});\r\n\t}\r\n};\r\n\r\n// Not perfect, as I don't think this solves the issue where some cards are mutually exclusive\r\nconst selectMinions = (minions: BoardEntity[], tribes: Race[], allCards: AllCardsService): BoardEntity[] => {\r\n\t// Step 1\r\n\tconst minionsByTribe: { [tribe: string]: BoardEntity[] } = {};\r\n\tfor (const minion of minions) {\r\n\t\tfor (const tribe of allCards.getCard(minion.cardId).races) {\r\n\t\t\tif (!minionsByTribe[tribe]) {\r\n\t\t\t\tminionsByTribe[tribe] = [];\r\n\t\t\t}\r\n\t\t\tminionsByTribe[tribe].push(minion);\r\n\t\t}\r\n\t}\r\n\tfor (const tribe of ALL_BG_RACES) {\r\n\t\tminionsByTribe[tribe] = shuffleArray(minionsByTribe[Race[tribe]] ?? []);\r\n\t}\r\n\r\n\tconst selectedMinions: BoardEntity[] = [];\r\n\r\n\t// Step 3\r\n\tfor (const tribe of tribes) {\r\n\t\tif (minionsByTribe[tribe]) {\r\n\t\t\tminionsByTribe[tribe].sort(\r\n\t\t\t\t(a, b) => allCards.getCard(a.cardId).races.length - allCards.getCard(b.cardId).races.length,\r\n\t\t\t);\r\n\t\t\tfor (const minion of minionsByTribe[tribe]) {\r\n\t\t\t\tif (!selectedMinions.includes(minion)) {\r\n\t\t\t\t\tselectedMinions.push(minion);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Step 4\r\n\treturn selectedMinions;\r\n};\r\n\r\nconst handleOzumatForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// Because of some interactions between start of combat hero powers, it can happen that Ozumat is already present\r\n\t// on the board when we receive the board state\r\n\tif (\r\n\t\tplayerBoard.length < 7 &&\r\n\t\t!playerBoard.some((e) => e.cardId === CardIds.Tentacular_OzumatsTentacleToken_BG23_HERO_201pt)\r\n\t) {\r\n\t\tconst tentacularSize = playerEntity.heroPowerInfo;\r\n\t\tconst tentacular = spawnEntities(\r\n\t\t\tCardIds.Tentacular_OzumatsTentacleToken_BG23_HERO_201pt,\r\n\t\t\t1,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t\tfriendly,\r\n\t\t\ttrue,\r\n\t\t\tfalse,\r\n\t\t\tfalse,\r\n\t\t);\r\n\t\ttentacular[0].attack = tentacularSize;\r\n\t\ttentacular[0].health = tentacularSize;\r\n\t\tconst indexFromRight = 0;\r\n\t\tperformEntitySpawns(\r\n\t\t\ttentacular,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerEntity,\r\n\t\t\tindexFromRight,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tspectator.registerPowerTarget(playerEntity, tentacular[0], playerBoard, playerEntity, opponentEntity);\r\n\t}\r\n};\r\n\r\nconst handlePlayerStartOfCombatHeroPowers = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tfriendly: boolean,\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tspectator: Spectator,\r\n): number => {\r\n\t// eslint-disable-next-line prefer-const\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\tconst playerHeroPowerId = playerEntity.heroPowerId || getHeroPowerForHero(playerEntity.cardId);\r\n\t// TODO: should this recompute the first attack order?\r\n\tif (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimLeftToken) {\r\n\t\tconst target = opponentBoard[0];\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimRightToken) {\r\n\t\tconst target = opponentBoard[opponentBoard.length - 1];\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimLowToken) {\r\n\t\tconst smallestHealthMinion = [...opponentBoard].sort((a, b) => a.health - b.health)[0];\r\n\t\tconst target = pickRandom(opponentBoard.filter((e) => e.health === smallestHealthMinion.health));\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t} else if (playerEntity.heroPowerUsed && playerHeroPowerId === CardIds.AimHighToken) {\r\n\t\tconst highestHealthMinion = [...opponentBoard].sort((a, b) => b.health - a.health)[0];\r\n\t\tconst target = pickRandom(opponentBoard.filter((e) => e.health === highestHealthMinion.health));\r\n\t\tconst damageDone = dealDamageToEnemy(\r\n\t\t\ttarget,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tnull,\r\n\t\t\tplayerEntity.heroPowerInfo2 ?? 0,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\t// processMinionDeath(playerBoard, playerEntity, opponentBoard, opponentEntity, allCards, cardsData, sharedState, spectator);\r\n\t\tplayerEntity.deadEyeDamageDone = damageDone;\r\n\t}\r\n\tprocessMinionDeath(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n\tif (shouldRecomputeCurrentAttacker) {\r\n\t\tconst previousCurrentAttacker = currentAttacker;\r\n\t\tcurrentAttacker =\r\n\t\t\tplayerBoard.length > opponentBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: 1\r\n\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t? friendly\r\n\t\t\t\t\t? 1\r\n\t\t\t\t\t: 0\r\n\t\t\t\t: currentAttacker;\r\n\t\t// console.debug(\r\n\t\t// \t'recompting current attacker',\r\n\t\t// \tcurrentAttacker,\r\n\t\t// \tplayerBoard.length,\r\n\t\t// \topponentBoard.length,\r\n\t\t// \tpreviousCurrentAttacker,\r\n\t\t// \tstringifySimple(playerBoard, allCards),\r\n\t\t// \tstringifySimple(opponentBoard, allCards),\r\n\t\t// );\r\n\t}\r\n\treturn currentAttacker;\r\n};\r\n\r\nexport const getHeroPowerForHero = (heroCardId: string): string => {\r\n\tswitch (heroCardId) {\r\n\t\tcase CardIds.IllidanStormrage_TB_BaconShop_HERO_08:\r\n\t\t\treturn CardIds.Wingmen;\r\n\t\tcase CardIds.TheLichKing_TB_BaconShop_HERO_22:\r\n\t\t\treturn CardIds.RebornRites;\r\n\t\tcase CardIds.ProfessorPutricide_BG25_HERO_100:\r\n\t\t\treturn CardIds.RagePotion;\r\n\t\tcase CardIds.Deathwing_TB_BaconShop_HERO_52:\r\n\t\t\treturn CardIds.AllWillBurn;\r\n\t\tcase CardIds.TeronGorefiend_BG25_HERO_103:\r\n\t\t\treturn CardIds.TeronGorefiend_RapidReanimation;\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const performStartOfCombatMinionsForPlayer = (\r\n\tattacker: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\t// Apparently, the board composition used for start of combat minion effects (like Red Whelp, and I assume it works the\r\n\t// same way for others like Prized Promo Drake or Mantid Queen) is the one that is used before Illidan's effect is handled.\r\n\t// Since this also runs before HP start of combat, we probably also use the state as it was before HP were triggered, like\r\n\t// Tamsin's Phylactery.\r\n\tattackingBoardBefore: BoardEntity[],\r\n\tdefendingBoardBefore: BoardEntity[],\r\n\tallCards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tsharedState: SharedState,\r\n\tgameState: BgsGameState,\r\n\tspectator: Spectator,\r\n): void => {\r\n\t// Don't forget to update START_OF_COMBAT_CARD_IDS\r\n\tif (attacker.cardId === CardIds.RedWhelp_BGS_019) {\r\n\t\tconst damage = attackingBoardBefore\r\n\t\t\t.map((entity) => allCards.getCard(entity.cardId).races)\r\n\t\t\t.filter((races) => isCorrectTribe(races, Race.DRAGON)).length;\r\n\t\tdealDamageToRandomEnemy(\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattacker,\r\n\t\t\tdamage,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (attacker.cardId === CardIds.RedWhelp_TB_BaconUps_102) {\r\n\t\tconst damage = attackingBoardBefore\r\n\t\t\t.map((entity) => allCards.getCard(entity.cardId).races)\r\n\t\t\t.filter((races) => isCorrectTribe(races, Race.DRAGON)).length;\r\n\t\tdealDamageToRandomEnemy(\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattacker,\r\n\t\t\tdamage,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t\tdealDamageToRandomEnemy(\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattacker,\r\n\t\t\tdamage,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tallCards,\r\n\t\t\tcardsData,\r\n\t\t\tsharedState,\r\n\t\t\tspectator,\r\n\t\t);\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.PrizedPromoDrake_BG21_014 ||\r\n\t\tattacker.cardId === CardIds.PrizedPromoDrake_BG21_014_G\r\n\t) {\r\n\t\tconst numberOfDragons = attackingBoardBefore\r\n\t\t\t.map((entity) => allCards.getCard(entity.cardId).races)\r\n\t\t\t.filter((races) => isCorrectTribe(races, Race.DRAGON)).length;\r\n\t\tconst neighbours = getNeighbours(attackingBoard, attacker);\r\n\t\tconst multiplier = attacker.cardId === CardIds.PrizedPromoDrake_BG21_014_G ? 2 : 1;\r\n\t\tneighbours.forEach((entity) => {\r\n\t\t\tmodifyAttack(entity, multiplier * numberOfDragons, attackingBoard, allCards);\r\n\t\t\tmodifyHealth(entity, multiplier * numberOfDragons, attackingBoard, allCards);\r\n\t\t\tafterStatsUpdate(entity, attackingBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(attacker, entity, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t});\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.ChoralMrrrglr_BG26_354 ||\r\n\t\tattacker.cardId === CardIds.ChoralMrrrglr_BG26_354_G\r\n\t) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.ChoralMrrrglr_BG26_354_G ? 2 : 1;\r\n\t\tmodifyAttack(attacker, multiplier * attackingBoardHero.globalInfo?.ChoralAttackBuff, attackingBoard, allCards);\r\n\t\tmodifyHealth(attacker, multiplier * attackingBoardHero.globalInfo?.ChoralHealthBuff, attackingBoard, allCards);\r\n\t\tafterStatsUpdate(attacker, attackingBoard, allCards);\r\n\t\tspectator.registerPowerTarget(attacker, attacker, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.AmberGuardian_BG24_500 ||\r\n\t\tattacker.cardId === CardIds.AmberGuardian_BG24_500_G\r\n\t) {\r\n\t\t// First try to get a target without divine shield, and if none is available, pick one with divine shield\r\n\t\tconst otherDragons = attackingBoard\r\n\t\t\t.filter((e) => hasCorrectTribe(e, Race.DRAGON, allCards))\r\n\t\t\t.filter((e) => e.entityId !== attacker.entityId);\r\n\t\tconst loops = attacker.cardId === CardIds.AmberGuardian_BG24_500_G ? 2 : 1;\r\n\t\tconst dragonsToConsider = otherDragons;\r\n\t\tfor (let i = 0; i < loops; i++) {\r\n\t\t\tconst otherDragon =\r\n\t\t\t\tpickRandom(dragonsToConsider.filter((e) => !e.divineShield)) ?? pickRandom(dragonsToConsider);\r\n\t\t\tif (otherDragon) {\r\n\t\t\t\tif (!otherDragon.divineShield) {\r\n\t\t\t\t\tupdateDivineShield(otherDragon, attackingBoard, true, allCards);\r\n\t\t\t\t}\r\n\t\t\t\tmodifyAttack(otherDragon, 2, attackingBoard, allCards);\r\n\t\t\t\tmodifyHealth(otherDragon, 2, attackingBoard, allCards);\r\n\t\t\t\tafterStatsUpdate(otherDragon, attackingBoard, allCards);\r\n\t\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\totherDragon,\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\tdragonsToConsider.splice(dragonsToConsider.indexOf(otherDragon), 1);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.SanctumRester_BG26_356 ||\r\n\t\tattacker.cardId === CardIds.SanctumRester_BG26_356_G\r\n\t) {\r\n\t\tconst buff = attacker.cardId === CardIds.SanctumRester_BG26_356_G ? 16 : 8;\r\n\t\t// First try to get a target without divine shield, and if none is available, pick one with divine shield\r\n\t\tconst otherDragons = attackingBoard\r\n\t\t\t.filter((e) => hasCorrectTribe(e, Race.DRAGON, allCards))\r\n\t\t\t.filter((e) => e.entityId !== attacker.entityId);\r\n\t\totherDragons.forEach((otherDragon) => {\r\n\t\t\tmodifyHealth(otherDragon, buff, attackingBoard, allCards);\r\n\t\t\tafterStatsUpdate(otherDragon, attackingBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\tattacker,\r\n\t\t\t\totherDragon,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t);\r\n\t\t});\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.Soulsplitter_BG25_023 ||\r\n\t\tattacker.cardId === CardIds.Soulsplitter_BG25_023_G\r\n\t) {\r\n\t\tconst numberOfTargets = attacker.cardId === CardIds.Soulsplitter_BG25_023_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfTargets; i++) {\r\n\t\t\tconst undeadsWithoutReborn = attackingBoard\r\n\t\t\t\t.filter((e) => hasCorrectTribe(e, Race.UNDEAD, allCards))\r\n\t\t\t\t.filter((e) => !e.reborn);\r\n\t\t\tconst chosenUndead = pickRandom(undeadsWithoutReborn);\r\n\t\t\tif (chosenUndead) {\r\n\t\t\t\tchosenUndead.reborn = true;\r\n\t\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tchosenUndead,\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}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.Crabby_BG22_HERO_000_Buddy ||\r\n\t\tattacker.cardId === CardIds.Crabby_BG22_HERO_000_Buddy_G\r\n\t) {\r\n\t\tconst neighbours = getNeighbours(attackingBoard, attacker);\r\n\t\tconst multiplier = attacker.cardId === CardIds.Crabby_BG22_HERO_000_Buddy_G ? 2 : 1;\r\n\t\tneighbours.forEach((entity) => {\r\n\t\t\tmodifyAttack(entity, multiplier * (attackingBoardHero.deadEyeDamageDone ?? 0), attackingBoard, allCards);\r\n\t\t\tmodifyHealth(entity, multiplier * (attackingBoardHero.deadEyeDamageDone ?? 0), attackingBoard, allCards);\r\n\t\t\tafterStatsUpdate(entity, attackingBoard, allCards);\r\n\t\t\tspectator.registerPowerTarget(attacker, entity, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t});\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.CorruptedMyrmidon_BG23_012 ||\r\n\t\tattacker.cardId === CardIds.CorruptedMyrmidon_BG23_012_G\r\n\t) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.CorruptedMyrmidon_BG23_012_G ? 2 : 1;\r\n\t\tmodifyAttack(attacker, multiplier * attacker.attack, attackingBoard, allCards);\r\n\t\tmodifyHealth(attacker, multiplier * attacker.health, attackingBoard, allCards);\r\n\t\tafterStatsUpdate(attacker, attackingBoard, allCards);\r\n\t\tspectator.registerPowerTarget(attacker, attacker, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.InterrogatorWhitemane_BG24_704 ||\r\n\t\tattacker.cardId === CardIds.InterrogatorWhitemane_BG24_704_G\r\n\t) {\r\n\t\tif (defendingBoard.length > 0) {\r\n\t\t\tconst attackerIndex = attackingBoard.indexOf(attacker);\r\n\t\t\tconst defenderPosition = attackerIndex - (attackingBoard.length - defendingBoard.length) / 2;\r\n\t\t\tif (Math.round(defenderPosition) === defenderPosition) {\r\n\t\t\t\tcastImpure(defendingBoard[defenderPosition], attacker, attackingBoard, spectator);\r\n\t\t\t} else {\r\n\t\t\t\tcastImpure(defendingBoard[defenderPosition - 0.5], attacker, attackingBoard, spectator);\r\n\t\t\t\tcastImpure(defendingBoard[defenderPosition + 0.5], attacker, attackingBoard, spectator);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (attacker.cardId === CardIds.MantidQueen_BG22_402 || attacker.cardId === CardIds.MantidQueen_BG22_402_G) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.MantidQueen_BG22_402_G ? 2 : 1;\r\n\t\tconst allRaces = attackingBoardBefore\r\n\t\t\t.map((entity) => entity.cardId)\r\n\t\t\t.flatMap((cardId) => allCards.getCard(cardId).races)\r\n\t\t\t.filter((race) => !!race && race !== Race[Race.BLANK]);\r\n\t\tconst totalRaces =\r\n\t\t\t[...new Set(allRaces.filter((race) => race !== Race[Race.ALL]))].length +\r\n\t\t\tallRaces.filter((race) => race === Race[Race.ALL]).length;\r\n\t\tfor (let i = 0; i < multiplier; i++) {\r\n\t\t\tfor (let j = 0; j < totalRaces; j++) {\r\n\t\t\t\tconst buffType = getRandomMantidQueenBuffType(attacker);\r\n\t\t\t\tswitch (buffType) {\r\n\t\t\t\t\tcase 'stats':\r\n\t\t\t\t\t\tmodifyAttack(attacker, 5, attackingBoard, allCards);\r\n\t\t\t\t\t\tmodifyHealth(attacker, 5, attackingBoard, allCards);\r\n\t\t\t\t\t\tafterStatsUpdate(attacker, attackingBoard, allCards);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'reborn':\r\n\t\t\t\t\t\tattacker.reborn = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'taunt':\r\n\t\t\t\t\t\tattacker.taunt = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 'windfury':\r\n\t\t\t\t\t\tattacker.windfury = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tspectator.registerPowerTarget(\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tattacker,\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}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.CarbonicCopy_BG27_503 ||\r\n\t\tattacker.cardId === CardIds.CarbonicCopy_BG27_503_G\r\n\t) {\r\n\t\tconst numberOfCopies = attacker.cardId === CardIds.CarbonicCopy_BG27_503_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfCopies; i++) {\r\n\t\t\tif (!!attackingBoard.length && attackingBoard.length < 7) {\r\n\t\t\t\tconst copy: BoardEntity = {\r\n\t\t\t\t\t...attacker,\r\n\t\t\t\t\tlastAffectedByEntity: null,\r\n\t\t\t\t};\r\n\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\tcopy.cardId,\r\n\t\t\t\t\t1,\r\n\t\t\t\t\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\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t\tattacker.friendly,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tcopy,\r\n\t\t\t\t);\r\n\t\t\t\tconst indexFromRight = attackingBoard.length - (attackingBoard.indexOf(attacker) + 1);\r\n\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\tnewMinions,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tindexFromRight,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t\tspectator.registerPowerTarget(attacker, copy, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.DiremuckForager_BG27_556 ||\r\n\t\tattacker.cardId === CardIds.DiremuckForager_BG27_556_G\r\n\t) {\r\n\t\tconst potentialTargets = attackingBoardHero.hand.filter((e) => !!e.cardId).filter((e) => !e.locked);\r\n\t\tif (potentialTargets.length > 0) {\r\n\t\t\tconst target = pickRandom(potentialTargets);\r\n\t\t\t// When it's the opponent, the game state already contains all the buffs\r\n\t\t\tif (target?.friendly) {\r\n\t\t\t\tconst diremuckBuff = attacker.cardId === CardIds.DiremuckForager_BG27_556_G ? 4 : 2;\r\n\t\t\t\tmodifyAttack(target, diremuckBuff, attackingBoard, allCards);\r\n\t\t\t\tmodifyHealth(target, diremuckBuff, attackingBoard, allCards);\r\n\t\t\t\tafterStatsUpdate(target, attackingBoard, allCards);\r\n\t\t\t\tspectator.registerPowerTarget(attacker, target, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t\t}\r\n\t\t\tif (attackingBoard.length < 7) {\r\n\t\t\t\ttarget.locked = true;\r\n\t\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\t\ttarget.cardId,\r\n\t\t\t\t\t1,\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\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t\tattacker.friendly,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\t{ ...target } as BoardEntity,\r\n\t\t\t\t);\r\n\t\t\t\tfor (const s of newMinions) {\r\n\t\t\t\t\ts.onCanceledSummon = () => (target.locked = false);\r\n\t\t\t\t}\r\n\t\t\t\tperformEntitySpawns(\r\n\t\t\t\t\tnewMinions,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tattackingBoard.length - (attackingBoard.indexOf(attacker) + 1),\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.HawkstriderHerald_BG27_079 ||\r\n\t\tattacker.cardId === CardIds.HawkstriderHerald_BG27_079_G\r\n\t) {\r\n\t\tconst multiplier = attacker.cardId === CardIds.HawkstriderHerald_BG27_079_G ? 2 : 1;\r\n\t\tfor (const entity of attackingBoard) {\r\n\t\t\tfor (let i = 0; i < multiplier; i++) {\r\n\t\t\t\tspectator.registerPowerTarget(attacker, entity, attackingBoard, attackingBoardHero, defendingBoardHero);\r\n\t\t\t\thandleDeathrattles(\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tentity,\r\n\t\t\t\t\tattackingBoard.length - 1 - attackingBoard.indexOf(entity),\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t[],\r\n\t\t\t\t\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t} else if (\r\n\t\tattacker.cardId === CardIds.AudaciousAnchor_BG28_904 ||\r\n\t\tattacker.cardId === CardIds.AudaciousAnchor_BG28_904_G\r\n\t) {\r\n\t\tconst iterations = attacker.cardId === CardIds.AudaciousAnchor_BG28_904_G ? 2 : 1;\r\n\t\tfor (let i = 0; i < iterations; i++) {\r\n\t\t\tconst targets = findNearestEnemies(\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattacker,\r\n\t\t\t\tattackingBoard.length - 1 - attackingBoard.indexOf(attacker),\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\t1,\r\n\t\t\t\tallCards,\r\n\t\t\t);\r\n\t\t\tif (!targets.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tconst target = targets[0];\r\n\t\t\twhile (attacker.health > 0 && target.health > 0 && !attacker.definitelyDead && !target.definitelyDead) {\r\n\t\t\t\t// Attackers don't alternate\r\n\t\t\t\t// See http://replays.firestoneapp.com/?reviewId=f9f6bf62-db73-49ad-8187-d2f8848b7f36&turn=17&action=0\r\n\t\t\t\tdoFullAttack(\r\n\t\t\t\t\tattacker,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\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\tallCards,\r\n\t\t\t\t\tcardsData,\r\n\t\t\t\t\tsharedState,\r\n\t\t\t\t\tspectator,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\tprocessMinionDeath(\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tallCards,\r\n\t\tcardsData,\r\n\t\tsharedState,\r\n\t\tspectator,\r\n\t);\r\n};\r\n\r\nconst applyAllWillBurn = (\r\n\tboard1: BoardEntity[],\r\n\tboard2: BoardEntity[],\r\n\tsourceEntity: BgsPlayerEntity | BoardEntity,\r\n\tallCards: AllCardsService,\r\n\tspectator: Spectator,\r\n): void => {\r\n\tfor (const entity of board1) {\r\n\t\tmodifyAttack(entity, 2, board1, allCards);\r\n\t\tafterStatsUpdate(entity, board1, allCards);\r\n\t\tspectator.registerPowerTarget(sourceEntity, entity, board1, null, null);\r\n\t}\r\n\tfor (const entity of board2) {\r\n\t\tmodifyAttack(entity, 2, board2, allCards);\r\n\t\tafterStatsUpdate(entity, board2, allCards);\r\n\t\tspectator.registerPowerTarget(sourceEntity, entity, board2, null, null);\r\n\t}\r\n};\r\n\r\nconst castImpure = (entity: BoardEntity, source: BoardEntity, board: BoardEntity[], spectator: Spectator) => {\r\n\tif (!entity) {\r\n\t\treturn;\r\n\t}\r\n\tconst multiplier = source.cardId === CardIds.InterrogatorWhitemane_BG24_704_G ? 3 : 2;\r\n\tentity.taunt = true;\r\n\tentity.damageMultiplier = entity.damageMultiplier ?? 1;\r\n\tentity.damageMultiplier *= multiplier;\r\n\tspectator.registerPowerTarget(source, entity, board, null, null);\r\n};\r\n\r\nconst getRandomMantidQueenBuffType = (entity: BoardEntity): 'stats' | 'reborn' | 'windfury' | 'taunt' => {\r\n\tconst possibilities: ('stats' | 'reborn' | 'windfury' | 'taunt')[] = ['stats'];\r\n\tif (!entity.reborn) {\r\n\t\tpossibilities.push('reborn');\r\n\t}\r\n\tif (!entity.windfury) {\r\n\t\tpossibilities.push('windfury');\r\n\t}\r\n\tif (!entity.taunt) {\r\n\t\tpossibilities.push('taunt');\r\n\t}\r\n\treturn pickRandom(possibilities);\r\n};\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestone-hs/simulate-bgs-battle",
3
- "version": "1.1.351",
3
+ "version": "1.1.352",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "lint": "eslint --color --fix --ext .ts .",