@firestone-hs/simulate-bgs-battle 1.1.762 → 1.1.763

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.
@@ -35,6 +35,7 @@ export interface BgsPlayerEntity {
35
35
  rapidReanimationMinion?: BoardEntity;
36
36
  rapidReanimationIndexFromLeft?: number;
37
37
  rapidReanimationIndexFromRight?: number;
38
+ leftMostAttacked?: number;
38
39
  }
39
40
  export interface BgsHeroPower {
40
41
  cardId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"bgs-player-entity.js","sourceRoot":"","sources":["../src/bgs-player-entity.ts"],"names":[],"mappings":"","sourcesContent":["import { GameTag } from '@firestone-hs/reference-data';\r\nimport { BoardEnchantment, BoardEntity } from './board-entity';\r\nimport { BoardSecret } from './board-secret';\r\n\r\nexport interface BgsPlayerEntity {\r\n\tcardId: string;\r\n\t// readonly nonGhostCardId?: string;\r\n\thpLeft: number;\r\n\treadonly tavernTier: number;\r\n\theroPowers: readonly BgsHeroPower[];\r\n\r\n\t/** @deprecated */\r\n\theroPowerId?: string | undefined | null;\r\n\t/** @deprecated */\r\n\treadonly heroPowerEntityId?: number;\r\n\t/** @deprecated */\r\n\treadonly heroPowerUsed?: boolean;\r\n\t/** @deprecated */\r\n\treadonly heroPowerInfo?: number | string;\r\n\t/** @deprecated */\r\n\theroPowerInfo2?: number;\r\n\t/** @deprecated */\r\n\tavengeCurrent?: number;\r\n\t/** @deprecated */\r\n\tavengeDefault?: number;\r\n\t// For Ozumat\r\n\t/** @deprecated */\r\n\theroPowerActivated?: boolean;\r\n\r\n\tfriendly?: boolean;\r\n\tentityId?: number;\r\n\tquestEntities: BgsQuestEntity[];\r\n\tquestRewards?: string[];\r\n\tquestRewardEntities?: {\r\n\t\tcardId: string;\r\n\t\tentityId: number;\r\n\t\tavengeDefault?: number;\r\n\t\tavengeCurrent?: number;\r\n\t\tscriptDataNum1: number;\r\n\t}[];\r\n\thand?: BoardEntity[];\r\n\tsecrets?: BoardSecret[];\r\n\ttrinkets?: BoardTrinket[];\r\n\tglobalInfo?: BgsPlayerGlobalInfo;\r\n\tstartOfCombatDone?: boolean;\r\n\t// Not really used, but needed for compatibility with BoardEntity\r\n\tenchantments?: BoardEnchantment[];\r\n\r\n\tdeadEyeDamageDone?: number;\r\n\trapidReanimationMinion?: BoardEntity;\r\n\trapidReanimationIndexFromLeft?: number;\r\n\trapidReanimationIndexFromRight?: number;\r\n}\r\n\r\nexport interface BgsHeroPower {\r\n\tcardId: string;\r\n\tentityId: number;\r\n\tused: boolean;\r\n\tinfo: number | string | BoardEntity;\r\n\tinfo2: number;\r\n\tinfo3: number;\r\n\tinfo4: number;\r\n\tinfo5: number;\r\n\tinfo6: number;\r\n\tscoreValue1?: number;\r\n\tscoreValue2?: number;\r\n\tscoreValue3?: number;\r\n\tavengeCurrent?: number;\r\n\tavengeDefault?: number;\r\n\tlocked?: number;\r\n\t// Always false when coming from the input, we set it in the appropriate place\r\n\tready?: boolean;\r\n\t// For Ozumat's Tentacular\r\n\tactivated?: boolean;\r\n}\r\n\r\nexport interface BgsPlayerGlobalInfo {\r\n\tEternalKnightsDeadThisGame?: number;\r\n\t// Flat buff carried over between combats, from Eternal Portrait. Unlike EternalKnightsDeadThisGame,\r\n\t// this is not doubled for golden Eternal Knights\r\n\tEternalKnightAttackBuff?: number;\r\n\tEternalKnightHealthBuff?: number;\r\n\tSanlaynScribesDeadThisGame?: number;\r\n\tUndeadAttackBonus?: number;\r\n\tUndeadHealthBonus?: number;\r\n\tHauntedCarapaceAttackBonus?: number;\r\n\tHauntedCarapaceHealthBonus?: number;\r\n\tFrostlingBonus?: number;\r\n\tBloodGemAttackBonus?: number;\r\n\tBloodGemHealthBonus?: number;\r\n\tGoldrinnBuffAtk?: number;\r\n\tGoldrinnBuffHealth?: number;\r\n\tSpellsCastThisGame?: number;\r\n\tTavernSpellsCastThisGame?: number;\r\n\t/** Cards discarded this game (combat-updated; tavern discards come from the client). */\r\n\tCardsDiscardedThisGame?: number;\r\n\t/** Resets each recruit turn (client or future sim hook). */\r\n\tTavernSpellsCastThisTurn?: number;\r\n\t/** Minions and tavern spells played this recruit turn (for Brazen Buccaneer, etc.). */\r\n\tCardsPlayedThisTurn?: number;\r\n\tElementalsPlayedThisTurn?: number;\r\n\tHighestTavernMinionAttack?: number;\r\n\tHighestTavernMinionHealth?: number;\r\n\tBackToBackCastThisGame?: number;\r\n\t/** Mama Mrrglton / Papa Mrrglton plays this game (both IDs count). */\r\n\tMrrgltonsPlayedThisGame?: number;\r\n\tPiratesPlayedThisGame?: number;\r\n\tBeastsSummonedThisGame?: number;\r\n\tBeastsSummonedThisCombat?: number;\r\n\tMagnetizedThisGame?: number;\r\n\tPiratesSummonedThisGame?: number;\r\n\tPirateAttackBonus?: number;\r\n\tMechAttackBonus?: number;\r\n\tAstralAutomatonsSummonedThisGame?: number;\r\n\tChoralAttackBuff?: number;\r\n\tChoralHealthBuff?: number;\r\n\tBeetleAttackBuff?: number;\r\n\tBeetleHealthBuff?: number;\r\n\t// There is some naming confusion. This is \"elementals grant more stats\", not \"elementals have more stats\"\r\n\tElementalAttackBuff?: number;\r\n\tElementalHealthBuff?: number;\r\n\t// Same for these pirates\r\n\tPirateAttackBuff?: number;\r\n\tPirateHealthBuff?: number;\r\n\tTavernSpellHealthBuff?: number;\r\n\tTavernSpellAttackBuff?: number;\r\n\tGoldSpentThisGame?: number;\r\n\tVolumizerHealthBuff?: number;\r\n\tVolumizerAttackBuff?: number;\r\n\tWhelpAttackBuff?: number;\r\n\tWhelpHealthBuff?: number;\r\n\tDeepBluesPlayed?: number;\r\n\tTastyLobstersBuff?: number;\r\n\tGoldenMinionsPlayedThisGame?: number;\r\n\r\n\tMutatedLasherAttackBuff?: number;\r\n\tMutatedLasherHealthBuff?: number;\r\n\tBattlecriesTriggeredThisGame?: number;\r\n\t/** Falling Sky Golem and similar; incremented when a deathrattle effect resolves for this hero's board. */\r\n\tDeathrattlesTriggeredThisGame?: number;\r\n\tFriendlyMinionsDeadLastCombat?: number;\r\n\tAdditionalAttack?: number;\r\n\t/**\r\n\t * Friendly minions with Rally that attacked this combat (once per attack action).\r\n\t * Full-env writes this back for Herding Horn free-Refresh grants.\r\n\t */\r\n\tRallyMinionAttacksThisCombat?: number;\r\n\t/** Fresh Perspective (and similar): free refreshes earned from combat deathrattles. */\r\n\tFreeRefreshesGainedThisCombat?: number;\r\n\t/** Demonology / Laboratory Assistant: Fodder injected into the next N refreshes. */\r\n\tfodderRefreshes?: number;\r\n\tfodderPerRefresh?: number;\r\n\t/**\r\n\t * Extra maximum gold next recruit turn (Timewarped Recycler Avenge, etc.).\r\n\t * Full-env copies this via combat globalInfo writeback.\r\n\t */\r\n\tmaxGoldBonus?: number;\r\n\r\n\t// --- BG 35.2 shop-adjacent (client may set; minion modules read where applicable) ---\r\n\t/** Cataclysmic Harbinger: last tavern spell card ID you cast (set in cast-tavern-spell). */\r\n\tLastTavernSpellCardId?: string;\r\n\t/** Diremuck Forager: how many hand summons are still owed when space opens (targets picked at resolve time). */\r\n\tDiremuckPendingSummons?: { foragerEntityId: number; remaining: number; spawnRight: boolean }[];\r\n}\r\n\r\nexport interface BgsQuestEntity {\r\n\tCardId: string;\r\n\tRewardDbfId: number;\r\n\tProgressCurrent: number;\r\n\tProgressTotal: number;\r\n}\r\n\r\nexport interface BoardTrinket {\r\n\tcardId: string;\r\n\tentityId: number;\r\n\tscriptDataNum1: number;\r\n\tscriptDataNum2?: number;\r\n\tscriptDataNum6?: number;\r\n\ttags?: {\r\n\t\t[key in GameTag]?: number;\r\n\t};\r\n\trememberedMinions?: BoardEntity[];\r\n\tavengeDefault?: number;\r\n\tavengeCurrent?: number;\r\n}\r\n"]}
1
+ {"version":3,"file":"bgs-player-entity.js","sourceRoot":"","sources":["../src/bgs-player-entity.ts"],"names":[],"mappings":"","sourcesContent":["import { GameTag } from '@firestone-hs/reference-data';\r\nimport { BoardEnchantment, BoardEntity } from './board-entity';\r\nimport { BoardSecret } from './board-secret';\r\n\r\nexport interface BgsPlayerEntity {\r\n\tcardId: string;\r\n\t// readonly nonGhostCardId?: string;\r\n\thpLeft: number;\r\n\treadonly tavernTier: number;\r\n\theroPowers: readonly BgsHeroPower[];\r\n\r\n\t/** @deprecated */\r\n\theroPowerId?: string | undefined | null;\r\n\t/** @deprecated */\r\n\treadonly heroPowerEntityId?: number;\r\n\t/** @deprecated */\r\n\treadonly heroPowerUsed?: boolean;\r\n\t/** @deprecated */\r\n\treadonly heroPowerInfo?: number | string;\r\n\t/** @deprecated */\r\n\theroPowerInfo2?: number;\r\n\t/** @deprecated */\r\n\tavengeCurrent?: number;\r\n\t/** @deprecated */\r\n\tavengeDefault?: number;\r\n\t// For Ozumat\r\n\t/** @deprecated */\r\n\theroPowerActivated?: boolean;\r\n\r\n\tfriendly?: boolean;\r\n\tentityId?: number;\r\n\tquestEntities: BgsQuestEntity[];\r\n\tquestRewards?: string[];\r\n\tquestRewardEntities?: {\r\n\t\tcardId: string;\r\n\t\tentityId: number;\r\n\t\tavengeDefault?: number;\r\n\t\tavengeCurrent?: number;\r\n\t\tscriptDataNum1: number;\r\n\t}[];\r\n\thand?: BoardEntity[];\r\n\tsecrets?: BoardSecret[];\r\n\ttrinkets?: BoardTrinket[];\r\n\tglobalInfo?: BgsPlayerGlobalInfo;\r\n\tstartOfCombatDone?: boolean;\r\n\t// Not really used, but needed for compatibility with BoardEntity\r\n\tenchantments?: BoardEnchantment[];\r\n\r\n\tdeadEyeDamageDone?: number;\r\n\trapidReanimationMinion?: BoardEntity;\r\n\trapidReanimationIndexFromLeft?: number;\r\n\trapidReanimationIndexFromRight?: number;\r\n\tleftMostAttacked?: number;\r\n}\r\n\r\nexport interface BgsHeroPower {\r\n\tcardId: string;\r\n\tentityId: number;\r\n\tused: boolean;\r\n\tinfo: number | string | BoardEntity;\r\n\tinfo2: number;\r\n\tinfo3: number;\r\n\tinfo4: number;\r\n\tinfo5: number;\r\n\tinfo6: number;\r\n\tscoreValue1?: number;\r\n\tscoreValue2?: number;\r\n\tscoreValue3?: number;\r\n\tavengeCurrent?: number;\r\n\tavengeDefault?: number;\r\n\tlocked?: number;\r\n\t// Always false when coming from the input, we set it in the appropriate place\r\n\tready?: boolean;\r\n\t// For Ozumat's Tentacular\r\n\tactivated?: boolean;\r\n}\r\n\r\nexport interface BgsPlayerGlobalInfo {\r\n\tEternalKnightsDeadThisGame?: number;\r\n\t// Flat buff carried over between combats, from Eternal Portrait. Unlike EternalKnightsDeadThisGame,\r\n\t// this is not doubled for golden Eternal Knights\r\n\tEternalKnightAttackBuff?: number;\r\n\tEternalKnightHealthBuff?: number;\r\n\tSanlaynScribesDeadThisGame?: number;\r\n\tUndeadAttackBonus?: number;\r\n\tUndeadHealthBonus?: number;\r\n\tHauntedCarapaceAttackBonus?: number;\r\n\tHauntedCarapaceHealthBonus?: number;\r\n\tFrostlingBonus?: number;\r\n\tBloodGemAttackBonus?: number;\r\n\tBloodGemHealthBonus?: number;\r\n\tGoldrinnBuffAtk?: number;\r\n\tGoldrinnBuffHealth?: number;\r\n\tSpellsCastThisGame?: number;\r\n\tTavernSpellsCastThisGame?: number;\r\n\t/** Cards discarded this game (combat-updated; tavern discards come from the client). */\r\n\tCardsDiscardedThisGame?: number;\r\n\t/** Resets each recruit turn (client or future sim hook). */\r\n\tTavernSpellsCastThisTurn?: number;\r\n\t/** Minions and tavern spells played this recruit turn (for Brazen Buccaneer, etc.). */\r\n\tCardsPlayedThisTurn?: number;\r\n\tElementalsPlayedThisTurn?: number;\r\n\tHighestTavernMinionAttack?: number;\r\n\tHighestTavernMinionHealth?: number;\r\n\tBackToBackCastThisGame?: number;\r\n\t/** Mama Mrrglton / Papa Mrrglton plays this game (both IDs count). */\r\n\tMrrgltonsPlayedThisGame?: number;\r\n\tPiratesPlayedThisGame?: number;\r\n\tBeastsSummonedThisGame?: number;\r\n\tBeastsSummonedThisCombat?: number;\r\n\tMagnetizedThisGame?: number;\r\n\tPiratesSummonedThisGame?: number;\r\n\tPirateAttackBonus?: number;\r\n\tMechAttackBonus?: number;\r\n\tAstralAutomatonsSummonedThisGame?: number;\r\n\tChoralAttackBuff?: number;\r\n\tChoralHealthBuff?: number;\r\n\tBeetleAttackBuff?: number;\r\n\tBeetleHealthBuff?: number;\r\n\t// There is some naming confusion. This is \"elementals grant more stats\", not \"elementals have more stats\"\r\n\tElementalAttackBuff?: number;\r\n\tElementalHealthBuff?: number;\r\n\t// Same for these pirates\r\n\tPirateAttackBuff?: number;\r\n\tPirateHealthBuff?: number;\r\n\tTavernSpellHealthBuff?: number;\r\n\tTavernSpellAttackBuff?: number;\r\n\tGoldSpentThisGame?: number;\r\n\tVolumizerHealthBuff?: number;\r\n\tVolumizerAttackBuff?: number;\r\n\tWhelpAttackBuff?: number;\r\n\tWhelpHealthBuff?: number;\r\n\tDeepBluesPlayed?: number;\r\n\tTastyLobstersBuff?: number;\r\n\tGoldenMinionsPlayedThisGame?: number;\r\n\r\n\tMutatedLasherAttackBuff?: number;\r\n\tMutatedLasherHealthBuff?: number;\r\n\tBattlecriesTriggeredThisGame?: number;\r\n\t/** Falling Sky Golem and similar; incremented when a deathrattle effect resolves for this hero's board. */\r\n\tDeathrattlesTriggeredThisGame?: number;\r\n\tFriendlyMinionsDeadLastCombat?: number;\r\n\tAdditionalAttack?: number;\r\n\t/**\r\n\t * Friendly minions with Rally that attacked this combat (once per attack action).\r\n\t * Full-env writes this back for Herding Horn free-Refresh grants.\r\n\t */\r\n\tRallyMinionAttacksThisCombat?: number;\r\n\t/** Fresh Perspective (and similar): free refreshes earned from combat deathrattles. */\r\n\tFreeRefreshesGainedThisCombat?: number;\r\n\t/** Demonology / Laboratory Assistant: Fodder injected into the next N refreshes. */\r\n\tfodderRefreshes?: number;\r\n\tfodderPerRefresh?: number;\r\n\t/**\r\n\t * Extra maximum gold next recruit turn (Timewarped Recycler Avenge, etc.).\r\n\t * Full-env copies this via combat globalInfo writeback.\r\n\t */\r\n\tmaxGoldBonus?: number;\r\n\r\n\t// --- BG 35.2 shop-adjacent (client may set; minion modules read where applicable) ---\r\n\t/** Cataclysmic Harbinger: last tavern spell card ID you cast (set in cast-tavern-spell). */\r\n\tLastTavernSpellCardId?: string;\r\n\t/** Diremuck Forager: how many hand summons are still owed when space opens (targets picked at resolve time). */\r\n\tDiremuckPendingSummons?: { foragerEntityId: number; remaining: number; spawnRight: boolean }[];\r\n}\r\n\r\nexport interface BgsQuestEntity {\r\n\tCardId: string;\r\n\tRewardDbfId: number;\r\n\tProgressCurrent: number;\r\n\tProgressTotal: number;\r\n}\r\n\r\nexport interface BoardTrinket {\r\n\tcardId: string;\r\n\tentityId: number;\r\n\tscriptDataNum1: number;\r\n\tscriptDataNum2?: number;\r\n\tscriptDataNum6?: number;\r\n\ttags?: {\r\n\t\t[key in GameTag]?: number;\r\n\t};\r\n\trememberedMinions?: BoardEntity[];\r\n\tavengeDefault?: number;\r\n\tavengeCurrent?: number;\r\n}\r\n"]}
@@ -41,6 +41,7 @@ export interface StartOfCombatCard extends Card {
41
41
  startOfCombat(trinket: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret, input: SoCInput): boolean | {
42
42
  hasTriggered: boolean;
43
43
  shouldRecomputeCurrentAttacker: boolean;
44
+ skipSummonsWhenSpace?: boolean;
44
45
  };
45
46
  }
46
47
  export declare const hasStartOfCombat: (card: Card) => card is StartOfCombatCard;
@@ -1 +1 @@
1
- {"version":3,"file":"card.interface.js","sourceRoot":"","sources":["../../src/cards/card.interface.ts"],"names":[],"mappings":";;;;AAyDO,MAAM,iBAAiB,GAAG,CAAC,IAAU,EAA8B,EAAE,CAC3E,CAAC,IAA2B,aAA3B,IAAI,uBAAJ,IAAI,CAAyB,cAAc,MAAK,SAAS,CAAC;AAD/C,QAAA,iBAAiB,qBAC8B;AASrD,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAA6B,EAAE,CACzE,CAAC,IAA0B,aAA1B,IAAI,uBAAJ,IAAI,CAAwB,aAAa,MAAK,SAAS,CAAC;AAD7C,QAAA,gBAAgB,oBAC6B;AAInD,MAAM,wBAAwB,GAAG,CAAC,IAAU,EAAqC,EAAE,CACzF,CAAC,IAAkC,aAAlC,IAAI,uBAAJ,IAAI,CAAgC,qBAAqB,MAAK,SAAS,CAAC;AAD7D,QAAA,wBAAwB,4BACqC;AAMnE,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAA2B,EAAE,CACzE,CAAC,IAAwB,aAAxB,IAAI,uBAAJ,IAAI,CAAsB,eAAe,MAAK,SAAS,CAAC;AAD7C,QAAA,kBAAkB,sBAC2B;AAKnD,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAiC,EAAE,CACjF,CAAC,IAA8B,aAA9B,IAAI,uBAAJ,IAAI,CAA4B,iBAAiB,MAAK,SAAS,CAAC;AADrD,QAAA,oBAAoB,wBACiC;AAK3D,MAAM,0BAA0B,GAAG,CAAC,IAAU,EAAuC,EAAE,CAC7F,CAAC,IAAoC,aAApC,IAAI,uBAAJ,IAAI,CAAkC,uBAAuB,MAAK,SAAS,CAAC;AADjE,QAAA,0BAA0B,8BACuC;AAKvE,MAAM,uBAAuB,GAAG,CAAC,IAAU,EAAoC,EAAE,CACvF,CAAC,IAAiC,aAAjC,IAAI,uBAAJ,IAAI,CAA+B,oBAAoB,MAAK,SAAS,CAAC;AAD3D,QAAA,uBAAuB,2BACoC;AASjE,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAqB,EAAE,CAAC,CAAC,IAAkB,aAAlB,IAAI,uBAAJ,IAAI,CAAgB,KAAK,MAAK,SAAS,CAAC;AAAvF,QAAA,QAAQ,YAA+E;AAQ7F,MAAM,iCAAiC,GAAG,CAAC,IAAU,EAA8C,EAAE,CAC3G,CAAC,IAA2C,aAA3C,IAAI,uBAAJ,IAAI,CAAyC,8BAA8B,MAAK,SAAS,CAAC;AAD/E,QAAA,iCAAiC,qCAC8C;AAQrF,MAAM,4BAA4B,GAAG,CAAC,IAAU,EAAyC,EAAE,CACjG,CAAC,IAAsC,aAAtC,IAAI,uBAAJ,IAAI,CAAoC,yBAAyB,MAAK,SAAS,CAAC;AADrE,QAAA,4BAA4B,gCACyC;AAQ3E,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAgC,EAAE,CAC/E,CAAC,IAA6B,aAA7B,IAAI,uBAAJ,IAAI,CAA2B,gBAAgB,MAAK,SAAS,CAAC;AADnD,QAAA,mBAAmB,uBACgC;AAKzD,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAgC,EAAE,CAC/E,CAAC,IAA6B,aAA7B,IAAI,uBAAJ,IAAI,CAA2B,UAAU,MAAK,SAAS,CAAC;AAD7C,QAAA,mBAAmB,uBAC0B;AAKnD,MAAM,YAAY,GAAG,CAAC,IAAU,EAAyB,EAAE,CAAC,CAAC,IAAsB,aAAtB,IAAI,uBAAJ,IAAI,CAAoB,SAAS,MAAK,SAAS,CAAC;AAAvG,QAAA,YAAY,gBAA2F;AAK7G,MAAM,WAAW,GAAG,CAAC,IAAU,EAAqB,EAAE,CAAC,CAAC,IAAkB,aAAlB,IAAI,uBAAJ,IAAI,CAAgB,QAAQ,MAAK,SAAS,CAAC;AAA7F,QAAA,WAAW,eAAkF;AAInG,MAAM,uBAAuB,GAAG,CAAC,IAAU,EAAoC,EAAE,CACvF,CAAC,IAAiC,aAAjC,IAAI,uBAAJ,IAAI,CAA+B,oBAAoB,MAAK,SAAS,CAAC;AAD3D,QAAA,uBAAuB,2BACoC;AAKjE,MAAM,qBAAqB,GAAG,CAAC,IAAU,EAAkC,EAAE,CACnF,CAAC,IAA+B,aAA/B,IAAI,uBAAJ,IAAI,CAA6B,kBAAkB,MAAK,SAAS,CAAC;AADvD,QAAA,qBAAqB,yBACkC;AAK7D,MAAM,iBAAiB,GAAG,CAAC,IAAU,EAA8B,EAAE,CAC3E,CAAC,IAA2B,aAA3B,IAAI,uBAAJ,IAAI,CAAyB,cAAc,MAAK,SAAS,CAAC;AAD/C,QAAA,iBAAiB,qBAC8B;AAKrD,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAiC,EAAE,CACjF,CAAC,IAA8B,aAA9B,IAAI,uBAAJ,IAAI,CAA4B,iBAAiB,MAAK,SAAS,CAAC;AADrD,QAAA,oBAAoB,wBACiC;AAK3D,MAAM,kCAAkC,GAAG,CAAC,IAAU,EAA+C,EAAE,CAC7G,CAAC,IAA4C,aAA5C,IAAI,uBAAJ,IAAI,CAA0C,wBAAwB,MAAK,SAAS,CAAC;AAD1E,QAAA,kCAAkC,sCACwC;AAKhF,MAAM,cAAc,GAAG,CAAC,IAAU,EAA2B,EAAE,CACrE,CAAC,IAAwB,aAAxB,IAAI,uBAAJ,IAAI,CAAsB,WAAW,MAAK,SAAS,CAAC;AADzC,QAAA,cAAc,kBAC2B;AAE/C,MAAM,0BAA0B,GAAG,CAAC,IAAU,EAAsC,EAAE,CAC5F,CAAC,IAAmC,aAAnC,IAAI,uBAAJ,IAAI,CAAiC,sBAAsB,MAAK,SAAS,CAAC;AAD/D,QAAA,0BAA0B,8BACqC;AAIrE,MAAM,yBAAyB,GAAG,CAAC,IAAU,EAAsC,EAAE,CAC3F,CAAC,IAAmC,aAAnC,IAAI,uBAAJ,IAAI,CAAiC,sBAAsB,MAAK,SAAS,CAAC;AAD/D,QAAA,yBAAyB,6BACsC;AAKrE,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAgC,EAAE,CAC/E,CAAC,IAA6B,aAA7B,IAAI,uBAAJ,IAAI,CAA2B,gBAAgB,MAAK,SAAS,CAAC;AADnD,QAAA,mBAAmB,uBACgC;AAMzD,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAiC,EAAE,CACjF,CAAC,IAA8B,aAA9B,IAAI,uBAAJ,IAAI,CAA4B,iBAAiB,MAAK,SAAS,CAAC;AADrD,QAAA,oBAAoB,wBACiC;AAO3D,MAAM,YAAY,GAAG,CAAC,IAAU,EAAyB,EAAE,CAAC,CAAC,IAAsB,aAAtB,IAAI,uBAAJ,IAAI,CAAoB,SAAS,MAAK,SAAS,CAAC;AAAvG,QAAA,YAAY,gBAA2F;AAK7G,MAAM,eAAe,GAAG,CAAC,IAAU,EAA4B,EAAE,CACvE,CAAC,IAAyB,aAAzB,IAAI,uBAAJ,IAAI,CAAuB,YAAY,MAAK,SAAS,CAAC;AAD3C,QAAA,eAAe,mBAC4B;AAKjD,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAgC,EAAE,CAC/E,CAAC,IAA6B,aAA7B,IAAI,uBAAJ,IAAI,CAA2B,gBAAgB,MAAK,SAAS,CAAC;AADnD,QAAA,mBAAmB,uBACgC;AAKzD,MAAM,yBAAyB,GAAG,CAAC,IAAU,EAAsC,EAAE,CAC3F,CAAC,IAAmC,aAAnC,IAAI,uBAAJ,IAAI,CAAiC,sBAAsB,MAAK,SAAS,CAAC;AAD/D,QAAA,yBAAyB,6BACsC;AAMrE,MAAM,8BAA8B,GAAG,CAAC,IAAU,EAA2C,EAAE,CACrG,CAAC,IAAwC,aAAxC,IAAI,uBAAJ,IAAI,CAAsC,2BAA2B,MAAK,SAAS,CAAC;AADzE,QAAA,8BAA8B,kCAC2C;AAK/E,MAAM,cAAc,GAAG,CAAC,IAAU,EAA2B,EAAE,CACrE,CAAC,IAAwB,aAAxB,IAAI,uBAAJ,IAAI,CAAsB,WAAW,MAAK,SAAS,CAAC;AADzC,QAAA,cAAc,kBAC2B;AAK/C,MAAM,uBAAuB,GAAG,CAAC,IAAU,EAAoC,EAAE,CACvF,CAAC,IAAiC,aAAjC,IAAI,uBAAJ,IAAI,CAA+B,oBAAoB,MAAK,SAAS,CAAC;AAD3D,QAAA,uBAAuB,2BACoC;AAMjE,MAAM,SAAS,GAAG,CAAC,IAAU,EAAsB,EAAE,CAAC,CAAC,IAAmB,aAAnB,IAAI,uBAAJ,IAAI,CAAiB,MAAM,MAAK,SAAS,CAAC;AAA3F,QAAA,SAAS,aAAkF;AAKjG,MAAM,uBAAuB,GAAG,CAAC,IAAU,EAAoC,EAAE,CACvF,CAAC,IAAiC,aAAjC,IAAI,uBAAJ,IAAI,CAA+B,oBAAoB,MAAK,SAAS,CAAC;AAD3D,QAAA,uBAAuB,2BACoC;AASjE,MAAM,yBAAyB,GAAG,CAAC,IAAU,EAAoC,EAAE,CACzF,CAAC,IAAiC,aAAjC,IAAI,uBAAJ,IAAI,CAA+B,sBAAsB,MAAK,SAAS,CAAC;AAD7D,QAAA,yBAAyB,6BACoC;AASnE,MAAM,oCAAoC,GAAG,CAAC,IAAU,EAA+C,EAAE,CAC/G,CAAC,IAA4C,aAA5C,IAAI,uBAAJ,IAAI,CAA0C,iCAAiC,MAAK,SAAS,CAAC;AADnF,QAAA,oCAAoC,wCAC+C;AAWzF,MAAM,8BAA8B,GAAG,CAAC,IAAU,EAA2C,EAAE,CACrG,CAAC,IAAwC,aAAxC,IAAI,uBAAJ,IAAI,CAAsC,iCAAiC,MAAK,SAAS,CAAC;AAD/E,QAAA,8BAA8B,kCACiD;AAKrF,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAiC,EAAE,CACjF,CAAC,IAA8B,aAA9B,IAAI,uBAAJ,IAAI,CAA4B,iBAAiB,MAAK,SAAS,CAAC;AADrD,QAAA,oBAAoB,wBACiC;AAK3D,MAAM,YAAY,GAAG,CAAC,IAAU,EAAyB,EAAE,CAAC,CAAC,IAAsB,aAAtB,IAAI,uBAAJ,IAAI,CAAoB,SAAS,MAAK,SAAS,CAAC;AAAvG,QAAA,YAAY,gBAA2F;AAK7G,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAA+B,EAAE,CAC7E,CAAC,IAA4B,aAA5B,IAAI,uBAAJ,IAAI,CAA0B,eAAe,MAAK,SAAS,CAAC;AADjD,QAAA,kBAAkB,sBAC+B;AAMvD,MAAM,YAAY,GAAG,CAAC,IAAU,EAAyB,EAAE,CAAC,CAAC,IAAsB,aAAtB,IAAI,uBAAJ,IAAI,CAAoB,SAAS,MAAK,SAAS,CAAC;AAAvG,QAAA,YAAY,gBAA2F;AAM7G,MAAM,wBAAwB,GAAG,CAAC,IAAU,EAAqC,EAAE,CACzF,CAAC,IAAkC,aAAlC,IAAI,uBAAJ,IAAI,CAAgC,qBAAqB,MAAK,SAAS,CAAC;AAD7D,QAAA,wBAAwB,4BACqC;AAUnE,MAAM,iBAAiB,GAAG,CAAC,IAAU,EAA8B,EAAE,CAC3E,CAAC,IAA2B,aAA3B,IAAI,uBAAJ,IAAI,CAAyB,cAAc,MAAK,SAAS,CAAC;AAD/C,QAAA,iBAAiB,qBAC8B;AAUrD,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAA+B,EAAE,CAC7E,CAAC,IAA4B,aAA5B,IAAI,uBAAJ,IAAI,CAA0B,eAAe,MAAK,SAAS,CAAC;AADjD,QAAA,kBAAkB,sBAC+B;AAUvD,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAgC,EAAE,CAC/E,CAAC,IAA6B,aAA7B,IAAI,uBAAJ,IAAI,CAA2B,gBAAgB,MAAK,SAAS,CAAC;AADnD,QAAA,mBAAmB,uBACgC;AAUzD,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAiC,EAAE,CACjF,CAAC,IAA8B,aAA9B,IAAI,uBAAJ,IAAI,CAA4B,iBAAiB,MAAK,SAAS,CAAC;AADrD,QAAA,oBAAoB,wBACiC;AAU3D,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAiC,EAAE,CACjF,CAAC,IAA8B,aAA9B,IAAI,uBAAJ,IAAI,CAA4B,iBAAiB,MAAK,SAAS,CAAC;AADrD,QAAA,oBAAoB,wBACiC;AAK3D,MAAM,iBAAiB,GAAG,CAAC,IAAU,EAA8B,EAAE,CAC3E,CAAC,IAA2B,aAA3B,IAAI,uBAAJ,IAAI,CAAyB,cAAc,MAAK,SAAS,CAAC;AAD/C,QAAA,iBAAiB,qBAC8B;AAKrD,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAgC,EAAE,CAC/E,CAAC,IAA6B,aAA7B,IAAI,uBAAJ,IAAI,CAA2B,gBAAgB,MAAK,SAAS,CAAC;AADnD,QAAA,mBAAmB,uBACgC;AAKzD,MAAM,YAAY,GAAG,CAAC,IAAU,EAAyB,EAAE,CAAC,CAAC,IAAsB,aAAtB,IAAI,uBAAJ,IAAI,CAAoB,SAAS,MAAK,SAAS,CAAC;AAAvG,QAAA,YAAY,gBAA2F;AAU7G,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAA+B,EAAE,CAC7E,CAAC,IAA4B,aAA5B,IAAI,uBAAJ,IAAI,CAA0B,eAAe,MAAK,SAAS,CAAC;AADjD,QAAA,kBAAkB,sBAC+B;AAKvD,MAAM,oCAAoC,GAAG,CAAC,IAAU,EAAiD,EAAE,CACjH,CAAC,IAA8C,aAA9C,IAAI,uBAAJ,IAAI,CAA4C,0BAA0B,MAAK,SAAS,CAAC;AAD9E,QAAA,oCAAoC,wCAC0C;AAKpF,MAAM,UAAU,GAAG,CAAC,IAAU,EAAuB,EAAE,CAAC,CAAC,IAAoB,aAApB,IAAI,uBAAJ,IAAI,CAAkB,OAAO,MAAK,SAAS,CAAC;AAA/F,QAAA,UAAU,cAAqF;AAKrG,MAAM,eAAe,GAAG,CAAC,IAAU,EAA4B,EAAE,CACvE,CAAC,IAAyB,aAAzB,IAAI,uBAAJ,IAAI,CAAuB,YAAY,MAAK,SAAS,CAAC;AAD3C,QAAA,eAAe,mBAC4B;AAUjD,MAAM,6BAA6B,GAAG,CAAC,IAAU,EAA0C,EAAE,CACnG,CAAC,IAAuC,aAAvC,IAAI,uBAAJ,IAAI,CAAqC,0BAA0B,MAAK,SAAS,CAAC;AADvE,QAAA,6BAA6B,iCAC0C;AAQ7E,MAAM,iBAAiB,GAAG,CAAC,IAAU,EAA8B,EAAE,CAC3E,CAAC,IAA2B,aAA3B,IAAI,uBAAJ,IAAI,CAAyB,cAAc,MAAK,SAAS,CAAC;AAD/C,QAAA,iBAAiB,qBAC8B;AAKrD,MAAM,oBAAoB,GAAG,CAAC,IAAU,EAAiC,EAAE,CACjF,CAAC,IAA8B,aAA9B,IAAI,uBAAJ,IAAI,CAA4B,iBAAiB,MAAK,SAAS,CAAC;AADrD,QAAA,oBAAoB,wBACiC;AAK3D,MAAM,wBAAwB,GAAG,CAAC,IAAU,EAAqC,EAAE,CACzF,CAAC,IAAkC,aAAlC,IAAI,uBAAJ,IAAI,CAAgC,qBAAqB,MAAK,SAAS,CAAC;AAD7D,QAAA,wBAAwB,4BACqC;AAKnE,MAAM,yBAAyB,GAAG,CAAC,IAAU,EAAsC,EAAE,CAC3F,CAAC,IAAmC,aAAnC,IAAI,uBAAJ,IAAI,CAAiC,sBAAsB,MAAK,SAAS,CAAC;AAD/D,QAAA,yBAAyB,6BACsC;AAKrE,MAAM,uBAAuB,GAAG,CAAC,IAAU,EAAoC,EAAE,CACvF,CAAC,IAAiC,aAAjC,IAAI,uBAAJ,IAAI,CAA+B,oBAAoB,MAAK,SAAS,CAAC;AAD3D,QAAA,uBAAuB,2BACoC;AAKjE,MAAM,mBAAmB,GAAG,CAAC,IAAU,EAAgC,EAAE,CAC/E,CAAC,IAA6B,aAA7B,IAAI,uBAAJ,IAAI,CAA2B,gBAAgB,MAAK,SAAS,CAAC;AADnD,QAAA,mBAAmB,uBACgC;AAKzD,MAAM,cAAc,GAAG,CAAC,IAAU,EAA2B,EAAE,CACrE,CAAC,IAAwB,aAAxB,IAAI,uBAAJ,IAAI,CAAsB,WAAW,MAAK,SAAS,CAAC;AADzC,QAAA,cAAc,kBAC2B;AAK/C,MAAM,sBAAsB,GAAG,CAAC,IAAU,EAAmC,EAAE,CACrF,CAAC,IAAgC,aAAhC,IAAI,uBAAJ,IAAI,CAA8B,mBAAmB,MAAK,SAAS,CAAC;AADzD,QAAA,sBAAsB,0BACmC;AAK/D,MAAM,uBAAuB,GAAG,CAAC,IAAU,EAAoC,EAAE,CACvF,CAAC,IAAiC,aAAjC,IAAI,uBAAJ,IAAI,CAA+B,oBAAoB,MAAK,SAAS,CAAC;AAD3D,QAAA,uBAAuB,2BACoC;AAKjE,MAAM,sBAAsB,GAAG,CAAC,IAAU,EAAmC,EAAE,CACrF,CAAC,IAAgC,aAAhC,IAAI,uBAAJ,IAAI,CAA8B,mBAAmB,MAAK,SAAS,CAAC;AADzD,QAAA,sBAAsB,0BACmC;AAS/D,MAAM,iCAAiC,GAAG,CAAC,IAAU,EAA8C,EAAE,CAC3G,CAAC,IAA2C,aAA3C,IAAI,uBAAJ,IAAI,CAAyC,8BAA8B,MAAK,SAAS,CAAC;AAD/E,QAAA,iCAAiC,qCAC8C;AAKrF,MAAM,WAAW,GAAG,CAAC,IAAU,EAAwB,EAAE,CAAC,CAAC,IAAqB,aAArB,IAAI,uBAAJ,IAAI,CAAmB,QAAQ,MAAK,SAAS,CAAC;AAAnG,QAAA,WAAW,eAAwF","sourcesContent":["import { BgsPlayerEntity, BgsQuestEntity, BoardTrinket } from '../bgs-player-entity';\r\nimport { BoardEnchantment, BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { OnDivineShieldUpdatedInput } from '../keywords/divine-shield';\r\nimport { OnRebornUpdatedInput } from '../keywords/reborn';\r\nimport { OnStealthUpdatedInput } from '../keywords/stealth';\r\nimport { OnTauntUpdatedInput } from '../keywords/taunt';\r\nimport { OnVenomousUpdatedInput } from '../keywords/venomous';\r\nimport { OnWindfuryUpdatedInput } from '../keywords/windfury';\r\nimport { OnGlobalInfoUpdatedInput } from '../mechanics/player-global-effects';\r\nimport {\r\n\tOnDespawnInput,\r\n\tOnFriendlyMinionSummonedTrinketInput,\r\n\tOnOtherSpawnAuraInput,\r\n\tOnOtherSpawnInput,\r\n\tOnSpawnInput,\r\n} from '../simulation/add-minion-to-board';\r\nimport {\r\n\tOnAfterDeathInput,\r\n\tOnAfterFriendlyMinionDeathInput,\r\n\tOnDeathInput,\r\n\tOnMinionKilledInput,\r\n} from '../simulation/attack';\r\nimport { AvengeInput } from '../simulation/avenge';\r\nimport { BattlecryInput, OnBattlecryTriggeredInput } from '../simulation/battlecries';\r\nimport { PlayedBloodGemsOnAnyInput, PlayedBloodGemsOnMeInput } from '../simulation/blood-gems';\r\nimport { OnCardAddedToHandInput } from '../simulation/cards-in-hand';\r\nimport { AfterDealDamageInput, AfterFriendlyMinionDamagedInput } from '../simulation/damage-effects';\r\nimport { AfterHeroDamagedInput } from '../simulation/damage-to-hero';\r\nimport { DeathrattleTriggeredInput } from '../simulation/deathrattle-on-trigger';\r\nimport { FullGameState } from '../simulation/internal-game-state';\r\nimport {\r\n\tOnAfterMagnetizeInput,\r\n\tOnAfterMagnetizeSelfInput,\r\n\tOnBeforeMagnetizeInput,\r\n\tOnBeforeMagnetizeSelfInput,\r\n} from '../simulation/magnetize';\r\nimport { OnAttackInput } from '../simulation/on-attack';\r\nimport { OnMinionAttackedInput } from '../simulation/on-being-attacked';\r\nimport { RebornEffectInput } from '../simulation/reborn';\r\nimport { SoCInput } from '../simulation/start-of-combat/start-of-combat-input';\r\nimport { OnStatsChangedInput } from '../simulation/stats';\r\nimport { OnGildedInput } from '../simulation/utils/golden';\r\n\r\nexport interface Card {\r\n\t// Maybe should make this mandatory\r\n\tcardIds?: readonly string[];\r\n\t// Method syntax keeps parameters bivariant so implementations can narrow (e.g. BoardEntity).\r\n\tstartOfCombat?(\r\n\t\ttrinket: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\t\tinput: SoCInput,\r\n\t): boolean | { hasTriggered: boolean; shouldRecomputeCurrentAttacker: boolean };\r\n}\r\n\r\nexport interface DefaultChargesCard extends Card {\r\n\tdefaultCharges(entity: BoardEntity): number;\r\n}\r\nexport const hasDefaultCharges = (card: Card): card is DefaultChargesCard =>\r\n\t(card as DefaultChargesCard)?.defaultCharges !== undefined;\r\n\r\nexport interface StartOfCombatCard extends Card {\r\n\tstartOfCombatTiming?: StartOfCombatTiming;\r\n\tstartOfCombat(\r\n\t\ttrinket: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\t\tinput: SoCInput,\r\n\t): boolean | { hasTriggered: boolean; shouldRecomputeCurrentAttacker: boolean };\r\n}\r\nexport const hasStartOfCombat = (card: Card): card is StartOfCombatCard =>\r\n\t(card as StartOfCombatCard)?.startOfCombat !== undefined;\r\nexport interface StartOfCombatFromHandCard extends StartOfCombatCard {\r\n\tstartOfCombatFromHand: true;\r\n}\r\nexport const hasStartOfCombatFromHand = (card: Card): card is StartOfCombatFromHandCard =>\r\n\t(card as StartOfCombatFromHandCard)?.startOfCombatFromHand !== undefined;\r\nexport type StartOfCombatTiming = 'start-of-combat' | 'pre-combat' | 'illidan';\r\n\r\nexport interface TavernSpellCard extends Card {\r\n\tcastTavernSpell(spellCardId: string, input: CastSpellInput): void;\r\n}\r\nexport const hasCastTavernSpell = (card: Card): card is TavernSpellCard =>\r\n\t(card as TavernSpellCard)?.castTavernSpell !== undefined;\r\n\r\nexport interface OnTavernSpellCastCard extends Card {\r\n\tonTavernSpellCast(entity: BoardEntity | BoardTrinket, input: CastSpellInput): void;\r\n}\r\nexport const hasOnTavernSpellCast = (card: Card): card is OnTavernSpellCastCard =>\r\n\t(card as OnTavernSpellCastCard)?.onTavernSpellCast !== undefined;\r\n\r\nexport interface OnBeforeTavernSpellCastCard extends Card {\r\n\tonBeforeTavernSpellCast(entity: BoardEntity | BoardTrinket, input: CastSpellInput): void;\r\n}\r\nexport const hasOnBeforeTavernSpellCast = (card: Card): card is OnBeforeTavernSpellCastCard =>\r\n\t(card as OnBeforeTavernSpellCastCard)?.onBeforeTavernSpellCast !== undefined;\r\n\r\nexport interface AfterTavernSpellCastCard extends Card {\r\n\tafterTavernSpellCast(entity: BoardEntity | BoardTrinket, input: CastSpellInput): void;\r\n}\r\nexport const hasAfterTavernSpellCast = (card: Card): card is AfterTavernSpellCastCard =>\r\n\t(card as AfterTavernSpellCastCard)?.afterTavernSpellCast !== undefined;\r\n\r\n// Whenever this attacks\r\nexport interface RallyCard extends Card {\r\n\trally(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasRally = (card: Card): card is RallyCard => (card as RallyCard)?.rally !== undefined;\r\n\r\nexport interface OnWheneverAnotherMinionAttacksCard extends Card {\r\n\tonWheneverAnotherMinionAttacks(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasOnWheneverAnotherMinionAttacks = (card: Card): card is OnWheneverAnotherMinionAttacksCard =>\r\n\t(card as OnWheneverAnotherMinionAttacksCard)?.onWheneverAnotherMinionAttacks !== undefined;\r\n\r\nexport interface AfterAnotherMinionAttacksCard extends Card {\r\n\tafterAnotherMinionAttacks(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasAfterAnotherMinionAttacks = (card: Card): card is AfterAnotherMinionAttacksCard =>\r\n\t(card as AfterAnotherMinionAttacksCard)?.afterAnotherMinionAttacks !== undefined;\r\n\r\nexport interface AfterThisAttacksCard extends Card {\r\n\tafterThisAttacks(\r\n\t\tminion: BoardEntity,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasAfterThisAttacks = (card: Card): card is AfterThisAttacksCard =>\r\n\t(card as AfterThisAttacksCard)?.afterThisAttacks !== undefined;\r\n\r\nexport interface OnMinionAttackedCard extends Card {\r\n\tonAttacked(minion: BoardEntity, input: OnMinionAttackedInput): void;\r\n}\r\nexport const hasOnMinionAttacked = (card: Card): card is OnMinionAttackedCard =>\r\n\t(card as OnMinionAttackedCard)?.onAttacked !== undefined;\r\n\r\nexport interface OnSpawnedCard extends Card {\r\n\tonSpawned(minion: BoardEntity, input: OnSpawnInput): void;\r\n}\r\nexport const hasOnSpawned = (card: Card): card is OnSpawnedCard => (card as OnSpawnedCard)?.onSpawned !== undefined;\r\n\r\nexport interface DeityCard extends Card {\r\n\tonAwaken(minion: BoardEntity, input: DeityAwakenInput): void;\r\n}\r\nexport const hasOnAwaken = (card: Card): card is DeityCard => (card as DeityCard)?.onAwaken !== undefined;\r\nexport interface OnSpawnedEnchantmentCard extends Card {\r\n\tonSpawnedEnchantment(minion: BoardEntity, enchantment: BoardEnchantment, input: OnSpawnInput): void;\r\n}\r\nexport const hasOnSpawnedEnchantment = (card: Card): card is OnSpawnedEnchantmentCard =>\r\n\t(card as OnSpawnedEnchantmentCard)?.onSpawnedEnchantment !== undefined;\r\n\r\nexport interface OnOtherSpawnedAuraCard extends Card {\r\n\tonOtherSpawnedAura(minion: BoardEntity, input: OnOtherSpawnAuraInput): void;\r\n}\r\nexport const hasOnOtherAuraSpawned = (card: Card): card is OnOtherSpawnedAuraCard =>\r\n\t(card as OnOtherSpawnedAuraCard)?.onOtherSpawnedAura !== undefined;\r\n\r\nexport interface OnOtherSpawnedCard extends Card {\r\n\tonOtherSpawned(minion: BoardEntity | BoardTrinket, input: OnOtherSpawnInput): void;\r\n}\r\nexport const hasOnOtherSpawned = (card: Card): card is OnOtherSpawnedCard =>\r\n\t(card as OnOtherSpawnedCard)?.onOtherSpawned !== undefined;\r\n\r\nexport interface AfterOtherSpawnedCard extends Card {\r\n\tafterOtherSpawned(minion: BoardEntity | BoardTrinket, input: OnOtherSpawnInput): void;\r\n}\r\nexport const hasAfterOtherSpawned = (card: Card): card is AfterOtherSpawnedCard =>\r\n\t(card as AfterOtherSpawnedCard)?.afterOtherSpawned !== undefined;\r\n\r\nexport interface OnFriendlyMinionSummonedTrinketCard extends Card {\r\n\tonFriendlyMinionSummoned(trinket: BoardTrinket, input: OnFriendlyMinionSummonedTrinketInput): void;\r\n}\r\nexport const hasOnFriendlyMinionSummonedTrinket = (card: Card): card is OnFriendlyMinionSummonedTrinketCard =>\r\n\t(card as OnFriendlyMinionSummonedTrinketCard)?.onFriendlyMinionSummoned !== undefined;\r\n\r\nexport interface OnDespawnedCard extends Card {\r\n\tonDespawned(minion: BoardEntity, input: OnDespawnInput): void;\r\n}\r\nexport const hasOnDespawned = (card: Card): card is OnDespawnedCard =>\r\n\t(card as OnDespawnedCard)?.onDespawned !== undefined;\r\n\r\nexport const OnDespawnedEnchantmentCard = (card: Card): card is OnDespawnedEnchantmentCard =>\r\n\t(card as OnDespawnedEnchantmentCard)?.onDespawnedEnchantment !== undefined;\r\nexport interface OnDespawnedEnchantmentCard extends Card {\r\n\tonDespawnedEnchantment(minion: BoardEntity, enchantment: BoardEnchantment, input: OnDespawnInput): void;\r\n}\r\nexport const hasOnDespawnedEnchantment = (card: Card): card is OnDespawnedEnchantmentCard =>\r\n\t(card as OnDespawnedEnchantmentCard)?.onDespawnedEnchantment !== undefined;\r\n\r\nexport interface DeathrattleSpawnCard extends Card {\r\n\tdeathrattleSpawn(minion: BoardEntity, input: DeathrattleTriggeredInput): readonly BoardEntity[];\r\n}\r\nexport const hasDeathrattleSpawn = (card: Card): card is DeathrattleSpawnCard =>\r\n\t(card as DeathrattleSpawnCard)?.deathrattleSpawn !== undefined;\r\n\r\n/** Deathrattle that does not return board spawns (hand buffs, stat grants, etc.). */\r\nexport interface DeathrattleEffectCard extends Card {\r\n\tdeathrattleEffect(minion: BoardEntity, input: DeathrattleTriggeredInput): void;\r\n}\r\nexport const hasDeathrattleEffect = (card: Card): card is DeathrattleEffectCard =>\r\n\t(card as DeathrattleEffectCard)?.deathrattleEffect !== undefined;\r\n\r\nexport interface BattlecryCard extends Card {\r\n\t// boolean return type is used only for conditional battlecries (eg cards that only work as battlecries if a specific trinket\r\n\t// is in game)\r\n\tbattlecry(minion: BoardEntity, input: BattlecryInput): boolean;\r\n}\r\nexport const hasBattlecry = (card: Card): card is BattlecryCard => (card as BattlecryCard)?.battlecry !== undefined;\r\n\r\nexport interface RebornEffectCard extends Card {\r\n\trebornEffect(minion: BoardEntity | BoardTrinket, input: RebornEffectInput): void;\r\n}\r\nexport const hasRebornEffect = (card: Card): card is RebornEffectCard =>\r\n\t(card as RebornEffectCard)?.rebornEffect !== undefined;\r\n\r\nexport interface RebornSelfEffectCard extends Card {\r\n\trebornSelfEffect(minion: BoardEntity, input: RebornEffectInput): void;\r\n}\r\nexport const hasRebornSelfEffect = (card: Card): card is RebornSelfEffectCard =>\r\n\t(card as RebornSelfEffectCard)?.rebornSelfEffect !== undefined;\r\n\r\nexport interface BeforeRebornSelfEffectCard extends Card {\r\n\tbeforeRebornSelfEffect(minion: BoardEntity, input: RebornEffectInput): void;\r\n}\r\nexport const hasBeforeRebornSelfEffect = (card: Card): card is BeforeRebornSelfEffectCard =>\r\n\t(card as BeforeRebornSelfEffectCard)?.beforeRebornSelfEffect !== undefined;\r\n\r\n// When a minion is reborn, some attributes need to be transferred to the new minion\r\nexport interface RebornSelfAttributeTransferCard extends Card {\r\n\trebornSelfAttributeTransfer: (keyof BoardEntity)[];\r\n}\r\nexport const hasRebornSelfAttributeTransfer = (card: Card): card is RebornSelfAttributeTransferCard =>\r\n\t(card as RebornSelfAttributeTransferCard)?.rebornSelfAttributeTransfer !== undefined;\r\n\r\nexport interface AfterRebornCard extends Card {\r\n\tafterReborn(minion: BoardEntity | BoardTrinket, input: RebornEffectInput): void;\r\n}\r\nexport const hasAfterReborn = (card: Card): card is AfterRebornCard =>\r\n\t(card as AfterRebornCard)?.afterReborn !== undefined;\r\n\r\nexport interface OnBattlecryTriggeredCard extends Card {\r\n\tonBattlecryTriggered(minion: BoardEntity | BoardTrinket, input: OnBattlecryTriggeredInput): void;\r\n}\r\nexport const hasOnBattlecryTriggered = (card: Card): card is OnBattlecryTriggeredCard =>\r\n\t(card as OnBattlecryTriggeredCard)?.onBattlecryTriggered !== undefined;\r\n\r\nexport interface AvengeCard extends Card {\r\n\tavenge(minion: BoardEntity | BoardTrinket, input: AvengeInput): void | readonly BoardEntity[];\r\n\tbaseAvengeValue(cardId: string): number;\r\n}\r\nexport const hasAvenge = (card: Card): card is AvengeCard => (card as AvengeCard)?.avenge !== undefined;\r\n\r\nexport interface DefaultScriptDataNumCard extends Card {\r\n\tdefaultScriptDataNum(cardId: string): number;\r\n}\r\nexport const hasDefaultScriptDataNum = (card: Card): card is DefaultScriptDataNumCard =>\r\n\t(card as DefaultScriptDataNumCard)?.defaultScriptDataNum !== undefined;\r\n\r\n/** To use when another deathrattle is triggered */\r\nexport interface DeathrattleTriggeredCard extends Card {\r\n\tonDeathrattleTriggered(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t): void;\r\n}\r\nexport const hasOnDeathrattleTriggered = (card: Card): card is DeathrattleTriggeredCard =>\r\n\t(card as DeathrattleTriggeredCard)?.onDeathrattleTriggered !== undefined;\r\n\r\nexport interface DeathrattleTriggeredEnchantmentCard extends Card {\r\n\tonDeathrattleTriggeredEnchantment(\r\n\t\tenchantedMinion: BoardEntity,\r\n\t\tenchantment: BoardEnchantment,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t): void;\r\n}\r\nexport const hasOnDeathrattleTriggeredEnchantment = (card: Card): card is DeathrattleTriggeredEnchantmentCard =>\r\n\t(card as DeathrattleTriggeredEnchantmentCard)?.onDeathrattleTriggeredEnchantment !== undefined;\r\n\r\n/** Despite the name, this covers all deathrattle effects on an enchantment, not just the spawning ones */\r\nexport interface DeathrattleSpawnEnchantmentCard extends Card {\r\n\tdeathrattleSpawnEnchantmentEffect(\r\n\t\tenchantment: BoardEnchantment,\r\n\t\tminion: BoardEntity | null | undefined,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t): readonly BoardEntity[];\r\n\tcardIds: readonly string[];\r\n}\r\nexport const hasDeathrattleSpawnEnchantment = (card: Card): card is DeathrattleSpawnEnchantmentCard =>\r\n\t(card as DeathrattleSpawnEnchantmentCard)?.deathrattleSpawnEnchantmentEffect !== undefined;\r\n\r\nexport interface OnCardAddedToHandCard extends Card {\r\n\tonCardAddedToHand(entity: BoardEntity | BgsQuestEntity | BoardTrinket, input: OnCardAddedToHandInput): void;\r\n}\r\nexport const hasOnCardAddedToHand = (card: Card): card is OnCardAddedToHandCard =>\r\n\t(card as OnCardAddedToHandCard)?.onCardAddedToHand !== undefined;\r\n\r\nexport interface OnDiscardCard extends Card {\r\n\tonDiscard(entity: BoardEntity | BoardTrinket, input: DiscardInput): void;\r\n}\r\nexport const hasOnDiscard = (card: Card): card is OnDiscardCard => (card as OnDiscardCard)?.onDiscard !== undefined;\r\n\r\nexport interface OnThisDiscardedCard extends Card {\r\n\tonThisDiscarded(card: BoardEntity, input: DiscardInput): void;\r\n}\r\nexport const hasOnThisDiscarded = (card: Card): card is OnThisDiscardedCard =>\r\n\t(card as OnThisDiscardedCard)?.onThisDiscarded !== undefined;\r\n\r\nexport interface EndOfTurnCard extends Card {\r\n\t// Use BattlecryInput because it's the only way end of turn effects are triggered\r\n\tendOfTurn(entity: BoardEntity, input: EndOfTurnInput): void;\r\n}\r\nexport const hasEndOfTurn = (card: Card): card is EndOfTurnCard => (card as EndOfTurnCard)?.endOfTurn !== undefined;\r\nexport type EndOfTurnInput = BattlecryInput;\r\n\r\nexport interface OnDivineShieldUpdatedCard extends Card {\r\n\tonDivineShieldUpdated(entity: BoardEntity | BoardTrinket, input: OnDivineShieldUpdatedInput): void;\r\n}\r\nexport const hasOnDivineShieldUpdated = (card: Card): card is OnDivineShieldUpdatedCard =>\r\n\t(card as OnDivineShieldUpdatedCard)?.onDivineShieldUpdated !== undefined;\r\n\r\nexport interface OnTauntUpdatedCard extends Card {\r\n\tonTauntUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnTauntUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnTauntUpdated = (card: Card): card is OnTauntUpdatedCard =>\r\n\t(card as OnTauntUpdatedCard)?.onTauntUpdated !== undefined;\r\n\r\nexport interface OnRebornUpdatedCard extends Card {\r\n\tonRebornUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnRebornUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnRebornUpdated = (card: Card): card is OnRebornUpdatedCard =>\r\n\t(card as OnRebornUpdatedCard)?.onRebornUpdated !== undefined;\r\n\r\nexport interface OnStealthUpdatedCard extends Card {\r\n\tonStealthUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnStealthUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnStealthUpdated = (card: Card): card is OnStealthUpdatedCard =>\r\n\t(card as OnStealthUpdatedCard)?.onStealthUpdated !== undefined;\r\n\r\nexport interface OnVenomousUpdatedCard extends Card {\r\n\tonVenomousUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnVenomousUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnVenomousUpdated = (card: Card): card is OnVenomousUpdatedCard =>\r\n\t(card as OnVenomousUpdatedCard)?.onVenomousUpdated !== undefined;\r\n\r\nexport interface OnWindfuryUpdatedCard extends Card {\r\n\tonWindfuryUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnWindfuryUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnWindfuryUpdated = (card: Card): card is OnWindfuryUpdatedCard =>\r\n\t(card as OnWindfuryUpdatedCard)?.onWindfuryUpdated !== undefined;\r\n\r\nexport interface OnStatsChangedCard extends Card {\r\n\tonStatsChanged(entity: BoardEntity, input: OnStatsChangedInput): void;\r\n}\r\nexport const hasOnStatsChanged = (card: Card): card is OnStatsChangedCard =>\r\n\t(card as OnStatsChangedCard)?.onStatsChanged !== undefined;\r\n\r\nexport interface AfterHeroDamagedCard extends Card {\r\n\tafterHeroDamaged(entity: BoardEntity | BoardTrinket, input: AfterHeroDamagedInput): void;\r\n}\r\nexport const hasAfterHeroDamaged = (card: Card): card is AfterHeroDamagedCard =>\r\n\t(card as AfterHeroDamagedCard)?.afterHeroDamaged !== undefined;\r\n\r\nexport interface OnDamagedCard extends Card {\r\n\tonDamaged(entity: BoardEntity, input: OnDamagedInput): void;\r\n}\r\nexport const hasOnDamaged = (card: Card): card is OnDamagedCard => (card as OnDamagedCard)?.onDamaged !== undefined;\r\n\r\nexport interface AfterDealDamageCard extends Card {\r\n\t// Called whenever damage is dealt, both on the friendly and enemy side\r\n\t// So you need to check the \"friendly\" flag\r\n\t// TODO: the \"after\" here waits for spawns, eg reborn / deathrattle\r\n\t// eg https://replays.firestoneapp.com/?reviewId=05860f41-1ea4-41f8-9c55-b6c854fa5f5a&turn=17&action=10\r\n\t// The reborn Rylak is buffed by Lord of the Ruins\r\n\tafterDealDamage(entity: BoardEntity, input: AfterDealDamageInput): void;\r\n}\r\nexport const hasAfterDealDamage = (card: Card): card is AfterDealDamageCard =>\r\n\t(card as AfterDealDamageCard)?.afterDealDamage !== undefined;\r\n\r\nexport interface AfterFriendlyMinionDamagedTrinketCard extends Card {\r\n\tafterFriendlyMinionDamaged(trinket: BoardTrinket, input: AfterFriendlyMinionDamagedInput): void;\r\n}\r\nexport const hasAfterFriendlyMinionDamagedTrinket = (card: Card): card is AfterFriendlyMinionDamagedTrinketCard =>\r\n\t(card as AfterFriendlyMinionDamagedTrinketCard)?.afterFriendlyMinionDamaged !== undefined;\r\n\r\nexport interface OnDeathCard extends Card {\r\n\tonDeath(entity: BoardEntity, input: OnDeathInput): void;\r\n}\r\nexport const hasOnDeath = (card: Card): card is OnDeathCard => (card as OnDeathCard)?.onDeath !== undefined;\r\n\r\nexport interface OnAfterDeathCard extends Card {\r\n\tonAfterDeath(entity: BoardEntity | BoardTrinket, input: OnAfterDeathInput): void;\r\n}\r\nexport const hasOnAfterDeath = (card: Card): card is OnAfterDeathCard =>\r\n\t(card as OnAfterDeathCard)?.onAfterDeath !== undefined;\r\n\r\n/**\r\n * After any friendly board minion dies (during `applyWheneverMinionDiesEffect`). Filter in the card\r\n * (e.g. only if `input.deadEntity.taunt`). Board minions and trinkets that implement this are dispatched\r\n * from `deathrattle-effects`.\r\n */\r\nexport interface OnAfterFriendlyMinionDeathCard extends Card {\r\n\tonAfterFriendlyMinionDeath(listener: BoardEntity | BoardTrinket, input: OnAfterFriendlyMinionDeathInput): void;\r\n}\r\nexport const hasOnAfterFriendlyMinionDeath = (card: Card): card is OnAfterFriendlyMinionDeathCard =>\r\n\t(card as OnAfterFriendlyMinionDeathCard)?.onAfterFriendlyMinionDeath !== undefined;\r\n\r\nexport interface OnMinionKilledCard extends Card {\r\n\tonMinionKilled(\r\n\t\tentity: BoardEntity,\r\n\t\tinput: OnMinionKilledInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasOnMinionKilled = (card: Card): card is OnMinionKilledCard =>\r\n\t(card as OnMinionKilledCard)?.onMinionKilled !== undefined;\r\n\r\nexport interface OnBeforeMagnetizeCard extends Card {\r\n\tonBeforeMagnetize(entity: BoardEntity | BoardTrinket, input: OnBeforeMagnetizeInput): void;\r\n}\r\nexport const hasOnBeforeMagnetize = (card: Card): card is OnBeforeMagnetizeCard =>\r\n\t(card as OnBeforeMagnetizeCard)?.onBeforeMagnetize !== undefined;\r\n\r\nexport interface OnBeforeMagnetizeSelfCard extends Card {\r\n\tonBeforeMagnetizeSelf(entity: BoardEntity, input: OnBeforeMagnetizeSelfInput): void;\r\n}\r\nexport const hasOnBeforeMagnetizeSelf = (card: Card): card is OnBeforeMagnetizeSelfCard =>\r\n\t(card as OnBeforeMagnetizeSelfCard)?.onBeforeMagnetizeSelf !== undefined;\r\n\r\nexport interface OnAfterMagnetizeToSelfCard extends Card {\r\n\tonAfterMagnetizeToSelf(entity: BoardEntity, input: OnAfterMagnetizeSelfInput): void;\r\n}\r\nexport const hasOnAfterMagnetizeToSelf = (card: Card): card is OnAfterMagnetizeToSelfCard =>\r\n\t(card as OnAfterMagnetizeToSelfCard)?.onAfterMagnetizeToSelf !== undefined;\r\n\r\nexport interface OnAfterMagnetizeSelfCard extends Card {\r\n\tonAfterMagnetizeSelf(entity: BoardEntity, input: OnAfterMagnetizeInput): void;\r\n}\r\nexport const hasOnAfterMagnetizeSelf = (card: Card): card is OnAfterMagnetizeSelfCard =>\r\n\t(card as OnAfterMagnetizeSelfCard)?.onAfterMagnetizeSelf !== undefined;\r\n\r\nexport interface OnAfterMagnetizeCard extends Card {\r\n\tonAfterMagnetize(entity: BoardEntity | BoardTrinket, input: OnAfterMagnetizeInput): void;\r\n}\r\nexport const hasOnAfterMagnetize = (card: Card): card is OnAfterMagnetizeCard =>\r\n\t(card as OnAfterMagnetizeCard)?.onAfterMagnetize !== undefined;\r\n\r\nexport interface OnSpawnFailCard extends Card {\r\n\tonSpawnFail(entity: BoardEntity, input: OnSpawnFailInput): void;\r\n}\r\nexport const hasOnSpawnFail = (card: Card): card is OnSpawnFailCard =>\r\n\t(card as OnSpawnFailCard)?.onSpawnFail !== undefined;\r\n\r\nexport interface PlayedBloodGemsOnMeCard extends Card {\r\n\tplayedBloodGemsOnMe(entity: BoardEntity, input: PlayedBloodGemsOnMeInput): void;\r\n}\r\nexport const hasPlayedBloodGemsOnMe = (card: Card): card is PlayedBloodGemsOnMeCard =>\r\n\t(card as PlayedBloodGemsOnMeCard)?.playedBloodGemsOnMe !== undefined;\r\n\r\nexport interface PlayedBloodGemsOnAnyCard extends Card {\r\n\tplayedBloodGemsOnAny(entity: BoardEntity, input: PlayedBloodGemsOnAnyInput): void;\r\n}\r\nexport const hasPlayedBloodGemsOnAny = (card: Card): card is PlayedBloodGemsOnAnyCard =>\r\n\t(card as PlayedBloodGemsOnAnyCard)?.playedBloodGemsOnAny !== undefined;\r\n\r\nexport interface OnGlobalInfoUpdatedCard extends Card {\r\n\tonGlobalInfoUpdated(entity: BoardEntity, input: OnGlobalInfoUpdatedInput): void;\r\n}\r\nexport const hasOnGlobalInfoUpdated = (card: Card): card is OnGlobalInfoUpdatedCard =>\r\n\t(card as OnGlobalInfoUpdatedCard)?.onGlobalInfoUpdated !== undefined;\r\n\r\nexport interface OnGlobalInfoUpdatedEnchantmentCard extends Card {\r\n\tonGlobalInfoUpdatedEnchantment(\r\n\t\tentity: BoardEntity,\r\n\t\tenchantment: BoardEnchantment,\r\n\t\tinput: OnGlobalInfoUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnGlobalInfoUpdatedEnchantment = (card: Card): card is OnGlobalInfoUpdatedEnchantmentCard =>\r\n\t(card as OnGlobalInfoUpdatedEnchantmentCard)?.onGlobalInfoUpdatedEnchantment !== undefined;\r\n\r\nexport interface OnGildedCard extends Card {\r\n\tonGilded(entity: BoardEntity, input: OnGildedInput): void;\r\n}\r\nexport const hasOnGilded = (card: Card): card is OnGildedCard => (card as OnGildedCard)?.onGilded !== undefined;\r\n\r\nexport interface OnSpawnFailInput {\r\n\tfailedSpawn: BoardEntity;\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n}\r\n\r\nexport interface DeityAwakenInput {\r\n\thero: BgsPlayerEntity;\r\n\tboard: BoardEntity[];\r\n\totherHero: BgsPlayerEntity;\r\n\totherBoard: BoardEntity[];\r\n\tgameState: FullGameState;\r\n}\r\n\r\nexport interface DiscardInput {\r\n\tdiscarded: BoardEntity;\r\n\thero: BgsPlayerEntity;\r\n\tboard: BoardEntity[];\r\n\totherHero: BgsPlayerEntity;\r\n\totherBoard: BoardEntity[];\r\n\tgameState: FullGameState;\r\n}\r\n\r\nexport interface CastSpellInput {\r\n\tspellCardId: string;\r\n\tsource: BoardEntity | BoardTrinket | BgsPlayerEntity;\r\n\ttarget: BoardEntity;\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherBoard: BoardEntity[];\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n}\r\nexport interface OnDamagedInput {\r\n\tdamagedEntity: BoardEntity;\r\n\tdamageDealer: BoardEntity | BgsPlayerEntity;\r\n\tdamage: number;\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n}\r\n"]}
1
+ {"version":3,"file":"card.interface.js","sourceRoot":"","sources":["../../src/cards/card.interface.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity, BgsQuestEntity, BoardTrinket } from '../bgs-player-entity';\r\nimport { BoardEnchantment, BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { OnDivineShieldUpdatedInput } from '../keywords/divine-shield';\r\nimport { OnRebornUpdatedInput } from '../keywords/reborn';\r\nimport { OnStealthUpdatedInput } from '../keywords/stealth';\r\nimport { OnTauntUpdatedInput } from '../keywords/taunt';\r\nimport { OnVenomousUpdatedInput } from '../keywords/venomous';\r\nimport { OnWindfuryUpdatedInput } from '../keywords/windfury';\r\nimport { OnGlobalInfoUpdatedInput } from '../mechanics/player-global-effects';\r\nimport {\r\n\tOnDespawnInput,\r\n\tOnFriendlyMinionSummonedTrinketInput,\r\n\tOnOtherSpawnAuraInput,\r\n\tOnOtherSpawnInput,\r\n\tOnSpawnInput,\r\n} from '../simulation/add-minion-to-board';\r\nimport {\r\n\tOnAfterDeathInput,\r\n\tOnAfterFriendlyMinionDeathInput,\r\n\tOnDeathInput,\r\n\tOnMinionKilledInput,\r\n} from '../simulation/attack';\r\nimport { AvengeInput } from '../simulation/avenge';\r\nimport { BattlecryInput, OnBattlecryTriggeredInput } from '../simulation/battlecries';\r\nimport { PlayedBloodGemsOnAnyInput, PlayedBloodGemsOnMeInput } from '../simulation/blood-gems';\r\nimport { OnCardAddedToHandInput } from '../simulation/cards-in-hand';\r\nimport { AfterDealDamageInput, AfterFriendlyMinionDamagedInput } from '../simulation/damage-effects';\r\nimport { AfterHeroDamagedInput } from '../simulation/damage-to-hero';\r\nimport { DeathrattleTriggeredInput } from '../simulation/deathrattle-on-trigger';\r\nimport { FullGameState } from '../simulation/internal-game-state';\r\nimport {\r\n\tOnAfterMagnetizeInput,\r\n\tOnAfterMagnetizeSelfInput,\r\n\tOnBeforeMagnetizeInput,\r\n\tOnBeforeMagnetizeSelfInput,\r\n} from '../simulation/magnetize';\r\nimport { OnAttackInput } from '../simulation/on-attack';\r\nimport { OnMinionAttackedInput } from '../simulation/on-being-attacked';\r\nimport { RebornEffectInput } from '../simulation/reborn';\r\nimport { SoCInput } from '../simulation/start-of-combat/start-of-combat-input';\r\nimport { OnStatsChangedInput } from '../simulation/stats';\r\nimport { OnGildedInput } from '../simulation/utils/golden';\r\n\r\nexport interface Card {\r\n\t// Maybe should make this mandatory\r\n\tcardIds?: readonly string[];\r\n\t// Method syntax keeps parameters bivariant so implementations can narrow (e.g. BoardEntity).\r\n\tstartOfCombat?(\r\n\t\ttrinket: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\t\tinput: SoCInput,\r\n\t): boolean | { hasTriggered: boolean; shouldRecomputeCurrentAttacker: boolean };\r\n}\r\n\r\nexport interface DefaultChargesCard extends Card {\r\n\tdefaultCharges(entity: BoardEntity): number;\r\n}\r\nexport const hasDefaultCharges = (card: Card): card is DefaultChargesCard =>\r\n\t(card as DefaultChargesCard)?.defaultCharges !== undefined;\r\n\r\nexport interface StartOfCombatCard extends Card {\r\n\tstartOfCombatTiming?: StartOfCombatTiming;\r\n\tstartOfCombat(\r\n\t\ttrinket: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\t\tinput: SoCInput,\r\n\t): boolean | { hasTriggered: boolean; shouldRecomputeCurrentAttacker: boolean; skipSummonsWhenSpace?: boolean };\r\n}\r\nexport const hasStartOfCombat = (card: Card): card is StartOfCombatCard =>\r\n\t(card as StartOfCombatCard)?.startOfCombat !== undefined;\r\nexport interface StartOfCombatFromHandCard extends StartOfCombatCard {\r\n\tstartOfCombatFromHand: true;\r\n}\r\nexport const hasStartOfCombatFromHand = (card: Card): card is StartOfCombatFromHandCard =>\r\n\t(card as StartOfCombatFromHandCard)?.startOfCombatFromHand !== undefined;\r\nexport type StartOfCombatTiming = 'start-of-combat' | 'pre-combat' | 'illidan';\r\n\r\nexport interface TavernSpellCard extends Card {\r\n\tcastTavernSpell(spellCardId: string, input: CastSpellInput): void;\r\n}\r\nexport const hasCastTavernSpell = (card: Card): card is TavernSpellCard =>\r\n\t(card as TavernSpellCard)?.castTavernSpell !== undefined;\r\n\r\nexport interface OnTavernSpellCastCard extends Card {\r\n\tonTavernSpellCast(entity: BoardEntity | BoardTrinket, input: CastSpellInput): void;\r\n}\r\nexport const hasOnTavernSpellCast = (card: Card): card is OnTavernSpellCastCard =>\r\n\t(card as OnTavernSpellCastCard)?.onTavernSpellCast !== undefined;\r\n\r\nexport interface OnBeforeTavernSpellCastCard extends Card {\r\n\tonBeforeTavernSpellCast(entity: BoardEntity | BoardTrinket, input: CastSpellInput): void;\r\n}\r\nexport const hasOnBeforeTavernSpellCast = (card: Card): card is OnBeforeTavernSpellCastCard =>\r\n\t(card as OnBeforeTavernSpellCastCard)?.onBeforeTavernSpellCast !== undefined;\r\n\r\nexport interface AfterTavernSpellCastCard extends Card {\r\n\tafterTavernSpellCast(entity: BoardEntity | BoardTrinket, input: CastSpellInput): void;\r\n}\r\nexport const hasAfterTavernSpellCast = (card: Card): card is AfterTavernSpellCastCard =>\r\n\t(card as AfterTavernSpellCastCard)?.afterTavernSpellCast !== undefined;\r\n\r\n// Whenever this attacks\r\nexport interface RallyCard extends Card {\r\n\trally(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasRally = (card: Card): card is RallyCard => (card as RallyCard)?.rally !== undefined;\r\n\r\nexport interface OnWheneverAnotherMinionAttacksCard extends Card {\r\n\tonWheneverAnotherMinionAttacks(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasOnWheneverAnotherMinionAttacks = (card: Card): card is OnWheneverAnotherMinionAttacksCard =>\r\n\t(card as OnWheneverAnotherMinionAttacksCard)?.onWheneverAnotherMinionAttacks !== undefined;\r\n\r\nexport interface AfterAnotherMinionAttacksCard extends Card {\r\n\tafterAnotherMinionAttacks(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasAfterAnotherMinionAttacks = (card: Card): card is AfterAnotherMinionAttacksCard =>\r\n\t(card as AfterAnotherMinionAttacksCard)?.afterAnotherMinionAttacks !== undefined;\r\n\r\nexport interface AfterThisAttacksCard extends Card {\r\n\tafterThisAttacks(\r\n\t\tminion: BoardEntity,\r\n\t\tinput: OnAttackInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasAfterThisAttacks = (card: Card): card is AfterThisAttacksCard =>\r\n\t(card as AfterThisAttacksCard)?.afterThisAttacks !== undefined;\r\n\r\nexport interface OnMinionAttackedCard extends Card {\r\n\tonAttacked(minion: BoardEntity, input: OnMinionAttackedInput): void;\r\n}\r\nexport const hasOnMinionAttacked = (card: Card): card is OnMinionAttackedCard =>\r\n\t(card as OnMinionAttackedCard)?.onAttacked !== undefined;\r\n\r\nexport interface OnSpawnedCard extends Card {\r\n\tonSpawned(minion: BoardEntity, input: OnSpawnInput): void;\r\n}\r\nexport const hasOnSpawned = (card: Card): card is OnSpawnedCard => (card as OnSpawnedCard)?.onSpawned !== undefined;\r\n\r\nexport interface DeityCard extends Card {\r\n\tonAwaken(minion: BoardEntity, input: DeityAwakenInput): void;\r\n}\r\nexport const hasOnAwaken = (card: Card): card is DeityCard => (card as DeityCard)?.onAwaken !== undefined;\r\nexport interface OnSpawnedEnchantmentCard extends Card {\r\n\tonSpawnedEnchantment(minion: BoardEntity, enchantment: BoardEnchantment, input: OnSpawnInput): void;\r\n}\r\nexport const hasOnSpawnedEnchantment = (card: Card): card is OnSpawnedEnchantmentCard =>\r\n\t(card as OnSpawnedEnchantmentCard)?.onSpawnedEnchantment !== undefined;\r\n\r\nexport interface OnOtherSpawnedAuraCard extends Card {\r\n\tonOtherSpawnedAura(minion: BoardEntity, input: OnOtherSpawnAuraInput): void;\r\n}\r\nexport const hasOnOtherAuraSpawned = (card: Card): card is OnOtherSpawnedAuraCard =>\r\n\t(card as OnOtherSpawnedAuraCard)?.onOtherSpawnedAura !== undefined;\r\n\r\nexport interface OnOtherSpawnedCard extends Card {\r\n\tonOtherSpawned(minion: BoardEntity | BoardTrinket, input: OnOtherSpawnInput): void;\r\n}\r\nexport const hasOnOtherSpawned = (card: Card): card is OnOtherSpawnedCard =>\r\n\t(card as OnOtherSpawnedCard)?.onOtherSpawned !== undefined;\r\n\r\nexport interface AfterOtherSpawnedCard extends Card {\r\n\tafterOtherSpawned(minion: BoardEntity | BoardTrinket, input: OnOtherSpawnInput): void;\r\n}\r\nexport const hasAfterOtherSpawned = (card: Card): card is AfterOtherSpawnedCard =>\r\n\t(card as AfterOtherSpawnedCard)?.afterOtherSpawned !== undefined;\r\n\r\nexport interface OnFriendlyMinionSummonedTrinketCard extends Card {\r\n\tonFriendlyMinionSummoned(trinket: BoardTrinket, input: OnFriendlyMinionSummonedTrinketInput): void;\r\n}\r\nexport const hasOnFriendlyMinionSummonedTrinket = (card: Card): card is OnFriendlyMinionSummonedTrinketCard =>\r\n\t(card as OnFriendlyMinionSummonedTrinketCard)?.onFriendlyMinionSummoned !== undefined;\r\n\r\nexport interface OnDespawnedCard extends Card {\r\n\tonDespawned(minion: BoardEntity, input: OnDespawnInput): void;\r\n}\r\nexport const hasOnDespawned = (card: Card): card is OnDespawnedCard =>\r\n\t(card as OnDespawnedCard)?.onDespawned !== undefined;\r\n\r\nexport const OnDespawnedEnchantmentCard = (card: Card): card is OnDespawnedEnchantmentCard =>\r\n\t(card as OnDespawnedEnchantmentCard)?.onDespawnedEnchantment !== undefined;\r\nexport interface OnDespawnedEnchantmentCard extends Card {\r\n\tonDespawnedEnchantment(minion: BoardEntity, enchantment: BoardEnchantment, input: OnDespawnInput): void;\r\n}\r\nexport const hasOnDespawnedEnchantment = (card: Card): card is OnDespawnedEnchantmentCard =>\r\n\t(card as OnDespawnedEnchantmentCard)?.onDespawnedEnchantment !== undefined;\r\n\r\nexport interface DeathrattleSpawnCard extends Card {\r\n\tdeathrattleSpawn(minion: BoardEntity, input: DeathrattleTriggeredInput): readonly BoardEntity[];\r\n}\r\nexport const hasDeathrattleSpawn = (card: Card): card is DeathrattleSpawnCard =>\r\n\t(card as DeathrattleSpawnCard)?.deathrattleSpawn !== undefined;\r\n\r\n/** Deathrattle that does not return board spawns (hand buffs, stat grants, etc.). */\r\nexport interface DeathrattleEffectCard extends Card {\r\n\tdeathrattleEffect(minion: BoardEntity, input: DeathrattleTriggeredInput): void;\r\n}\r\nexport const hasDeathrattleEffect = (card: Card): card is DeathrattleEffectCard =>\r\n\t(card as DeathrattleEffectCard)?.deathrattleEffect !== undefined;\r\n\r\nexport interface BattlecryCard extends Card {\r\n\t// boolean return type is used only for conditional battlecries (eg cards that only work as battlecries if a specific trinket\r\n\t// is in game)\r\n\tbattlecry(minion: BoardEntity, input: BattlecryInput): boolean;\r\n}\r\nexport const hasBattlecry = (card: Card): card is BattlecryCard => (card as BattlecryCard)?.battlecry !== undefined;\r\n\r\nexport interface RebornEffectCard extends Card {\r\n\trebornEffect(minion: BoardEntity | BoardTrinket, input: RebornEffectInput): void;\r\n}\r\nexport const hasRebornEffect = (card: Card): card is RebornEffectCard =>\r\n\t(card as RebornEffectCard)?.rebornEffect !== undefined;\r\n\r\nexport interface RebornSelfEffectCard extends Card {\r\n\trebornSelfEffect(minion: BoardEntity, input: RebornEffectInput): void;\r\n}\r\nexport const hasRebornSelfEffect = (card: Card): card is RebornSelfEffectCard =>\r\n\t(card as RebornSelfEffectCard)?.rebornSelfEffect !== undefined;\r\n\r\nexport interface BeforeRebornSelfEffectCard extends Card {\r\n\tbeforeRebornSelfEffect(minion: BoardEntity, input: RebornEffectInput): void;\r\n}\r\nexport const hasBeforeRebornSelfEffect = (card: Card): card is BeforeRebornSelfEffectCard =>\r\n\t(card as BeforeRebornSelfEffectCard)?.beforeRebornSelfEffect !== undefined;\r\n\r\n// When a minion is reborn, some attributes need to be transferred to the new minion\r\nexport interface RebornSelfAttributeTransferCard extends Card {\r\n\trebornSelfAttributeTransfer: (keyof BoardEntity)[];\r\n}\r\nexport const hasRebornSelfAttributeTransfer = (card: Card): card is RebornSelfAttributeTransferCard =>\r\n\t(card as RebornSelfAttributeTransferCard)?.rebornSelfAttributeTransfer !== undefined;\r\n\r\nexport interface AfterRebornCard extends Card {\r\n\tafterReborn(minion: BoardEntity | BoardTrinket, input: RebornEffectInput): void;\r\n}\r\nexport const hasAfterReborn = (card: Card): card is AfterRebornCard =>\r\n\t(card as AfterRebornCard)?.afterReborn !== undefined;\r\n\r\nexport interface OnBattlecryTriggeredCard extends Card {\r\n\tonBattlecryTriggered(minion: BoardEntity | BoardTrinket, input: OnBattlecryTriggeredInput): void;\r\n}\r\nexport const hasOnBattlecryTriggered = (card: Card): card is OnBattlecryTriggeredCard =>\r\n\t(card as OnBattlecryTriggeredCard)?.onBattlecryTriggered !== undefined;\r\n\r\nexport interface AvengeCard extends Card {\r\n\tavenge(minion: BoardEntity | BoardTrinket, input: AvengeInput): void | readonly BoardEntity[];\r\n\tbaseAvengeValue(cardId: string): number;\r\n}\r\nexport const hasAvenge = (card: Card): card is AvengeCard => (card as AvengeCard)?.avenge !== undefined;\r\n\r\nexport interface DefaultScriptDataNumCard extends Card {\r\n\tdefaultScriptDataNum(cardId: string): number;\r\n}\r\nexport const hasDefaultScriptDataNum = (card: Card): card is DefaultScriptDataNumCard =>\r\n\t(card as DefaultScriptDataNumCard)?.defaultScriptDataNum !== undefined;\r\n\r\n/** To use when another deathrattle is triggered */\r\nexport interface DeathrattleTriggeredCard extends Card {\r\n\tonDeathrattleTriggered(\r\n\t\tminion: BoardEntity | BoardTrinket | BoardEnchantment,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t): void;\r\n}\r\nexport const hasOnDeathrattleTriggered = (card: Card): card is DeathrattleTriggeredCard =>\r\n\t(card as DeathrattleTriggeredCard)?.onDeathrattleTriggered !== undefined;\r\n\r\nexport interface DeathrattleTriggeredEnchantmentCard extends Card {\r\n\tonDeathrattleTriggeredEnchantment(\r\n\t\tenchantedMinion: BoardEntity,\r\n\t\tenchantment: BoardEnchantment,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t): void;\r\n}\r\nexport const hasOnDeathrattleTriggeredEnchantment = (card: Card): card is DeathrattleTriggeredEnchantmentCard =>\r\n\t(card as DeathrattleTriggeredEnchantmentCard)?.onDeathrattleTriggeredEnchantment !== undefined;\r\n\r\n/** Despite the name, this covers all deathrattle effects on an enchantment, not just the spawning ones */\r\nexport interface DeathrattleSpawnEnchantmentCard extends Card {\r\n\tdeathrattleSpawnEnchantmentEffect(\r\n\t\tenchantment: BoardEnchantment,\r\n\t\tminion: BoardEntity | null | undefined,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t): readonly BoardEntity[];\r\n\tcardIds: readonly string[];\r\n}\r\nexport const hasDeathrattleSpawnEnchantment = (card: Card): card is DeathrattleSpawnEnchantmentCard =>\r\n\t(card as DeathrattleSpawnEnchantmentCard)?.deathrattleSpawnEnchantmentEffect !== undefined;\r\n\r\nexport interface OnCardAddedToHandCard extends Card {\r\n\tonCardAddedToHand(entity: BoardEntity | BgsQuestEntity | BoardTrinket, input: OnCardAddedToHandInput): void;\r\n}\r\nexport const hasOnCardAddedToHand = (card: Card): card is OnCardAddedToHandCard =>\r\n\t(card as OnCardAddedToHandCard)?.onCardAddedToHand !== undefined;\r\n\r\nexport interface OnDiscardCard extends Card {\r\n\tonDiscard(entity: BoardEntity | BoardTrinket, input: DiscardInput): void;\r\n}\r\nexport const hasOnDiscard = (card: Card): card is OnDiscardCard => (card as OnDiscardCard)?.onDiscard !== undefined;\r\n\r\nexport interface OnThisDiscardedCard extends Card {\r\n\tonThisDiscarded(card: BoardEntity, input: DiscardInput): void;\r\n}\r\nexport const hasOnThisDiscarded = (card: Card): card is OnThisDiscardedCard =>\r\n\t(card as OnThisDiscardedCard)?.onThisDiscarded !== undefined;\r\n\r\nexport interface EndOfTurnCard extends Card {\r\n\t// Use BattlecryInput because it's the only way end of turn effects are triggered\r\n\tendOfTurn(entity: BoardEntity, input: EndOfTurnInput): void;\r\n}\r\nexport const hasEndOfTurn = (card: Card): card is EndOfTurnCard => (card as EndOfTurnCard)?.endOfTurn !== undefined;\r\nexport type EndOfTurnInput = BattlecryInput;\r\n\r\nexport interface OnDivineShieldUpdatedCard extends Card {\r\n\tonDivineShieldUpdated(entity: BoardEntity | BoardTrinket, input: OnDivineShieldUpdatedInput): void;\r\n}\r\nexport const hasOnDivineShieldUpdated = (card: Card): card is OnDivineShieldUpdatedCard =>\r\n\t(card as OnDivineShieldUpdatedCard)?.onDivineShieldUpdated !== undefined;\r\n\r\nexport interface OnTauntUpdatedCard extends Card {\r\n\tonTauntUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnTauntUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnTauntUpdated = (card: Card): card is OnTauntUpdatedCard =>\r\n\t(card as OnTauntUpdatedCard)?.onTauntUpdated !== undefined;\r\n\r\nexport interface OnRebornUpdatedCard extends Card {\r\n\tonRebornUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnRebornUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnRebornUpdated = (card: Card): card is OnRebornUpdatedCard =>\r\n\t(card as OnRebornUpdatedCard)?.onRebornUpdated !== undefined;\r\n\r\nexport interface OnStealthUpdatedCard extends Card {\r\n\tonStealthUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnStealthUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnStealthUpdated = (card: Card): card is OnStealthUpdatedCard =>\r\n\t(card as OnStealthUpdatedCard)?.onStealthUpdated !== undefined;\r\n\r\nexport interface OnVenomousUpdatedCard extends Card {\r\n\tonVenomousUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnVenomousUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnVenomousUpdated = (card: Card): card is OnVenomousUpdatedCard =>\r\n\t(card as OnVenomousUpdatedCard)?.onVenomousUpdated !== undefined;\r\n\r\nexport interface OnWindfuryUpdatedCard extends Card {\r\n\tonWindfuryUpdated(\r\n\t\tentity: BoardEntity,\r\n\t\timpactedEntity: BoardEntity,\r\n\t\tpreviousValue: boolean,\r\n\t\tinput: OnWindfuryUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnWindfuryUpdated = (card: Card): card is OnWindfuryUpdatedCard =>\r\n\t(card as OnWindfuryUpdatedCard)?.onWindfuryUpdated !== undefined;\r\n\r\nexport interface OnStatsChangedCard extends Card {\r\n\tonStatsChanged(entity: BoardEntity, input: OnStatsChangedInput): void;\r\n}\r\nexport const hasOnStatsChanged = (card: Card): card is OnStatsChangedCard =>\r\n\t(card as OnStatsChangedCard)?.onStatsChanged !== undefined;\r\n\r\nexport interface AfterHeroDamagedCard extends Card {\r\n\tafterHeroDamaged(entity: BoardEntity | BoardTrinket, input: AfterHeroDamagedInput): void;\r\n}\r\nexport const hasAfterHeroDamaged = (card: Card): card is AfterHeroDamagedCard =>\r\n\t(card as AfterHeroDamagedCard)?.afterHeroDamaged !== undefined;\r\n\r\nexport interface OnDamagedCard extends Card {\r\n\tonDamaged(entity: BoardEntity, input: OnDamagedInput): void;\r\n}\r\nexport const hasOnDamaged = (card: Card): card is OnDamagedCard => (card as OnDamagedCard)?.onDamaged !== undefined;\r\n\r\nexport interface AfterDealDamageCard extends Card {\r\n\t// Called whenever damage is dealt, both on the friendly and enemy side\r\n\t// So you need to check the \"friendly\" flag\r\n\t// TODO: the \"after\" here waits for spawns, eg reborn / deathrattle\r\n\t// eg https://replays.firestoneapp.com/?reviewId=05860f41-1ea4-41f8-9c55-b6c854fa5f5a&turn=17&action=10\r\n\t// The reborn Rylak is buffed by Lord of the Ruins\r\n\tafterDealDamage(entity: BoardEntity, input: AfterDealDamageInput): void;\r\n}\r\nexport const hasAfterDealDamage = (card: Card): card is AfterDealDamageCard =>\r\n\t(card as AfterDealDamageCard)?.afterDealDamage !== undefined;\r\n\r\nexport interface AfterFriendlyMinionDamagedTrinketCard extends Card {\r\n\tafterFriendlyMinionDamaged(trinket: BoardTrinket, input: AfterFriendlyMinionDamagedInput): void;\r\n}\r\nexport const hasAfterFriendlyMinionDamagedTrinket = (card: Card): card is AfterFriendlyMinionDamagedTrinketCard =>\r\n\t(card as AfterFriendlyMinionDamagedTrinketCard)?.afterFriendlyMinionDamaged !== undefined;\r\n\r\nexport interface OnDeathCard extends Card {\r\n\tonDeath(entity: BoardEntity, input: OnDeathInput): void;\r\n}\r\nexport const hasOnDeath = (card: Card): card is OnDeathCard => (card as OnDeathCard)?.onDeath !== undefined;\r\n\r\nexport interface OnAfterDeathCard extends Card {\r\n\tonAfterDeath(entity: BoardEntity | BoardTrinket, input: OnAfterDeathInput): void;\r\n}\r\nexport const hasOnAfterDeath = (card: Card): card is OnAfterDeathCard =>\r\n\t(card as OnAfterDeathCard)?.onAfterDeath !== undefined;\r\n\r\n/**\r\n * After any friendly board minion dies (during `applyWheneverMinionDiesEffect`). Filter in the card\r\n * (e.g. only if `input.deadEntity.taunt`). Board minions and trinkets that implement this are dispatched\r\n * from `deathrattle-effects`.\r\n */\r\nexport interface OnAfterFriendlyMinionDeathCard extends Card {\r\n\tonAfterFriendlyMinionDeath(listener: BoardEntity | BoardTrinket, input: OnAfterFriendlyMinionDeathInput): void;\r\n}\r\nexport const hasOnAfterFriendlyMinionDeath = (card: Card): card is OnAfterFriendlyMinionDeathCard =>\r\n\t(card as OnAfterFriendlyMinionDeathCard)?.onAfterFriendlyMinionDeath !== undefined;\r\n\r\nexport interface OnMinionKilledCard extends Card {\r\n\tonMinionKilled(\r\n\t\tentity: BoardEntity,\r\n\t\tinput: OnMinionKilledInput,\r\n\t): { dmgDoneByAttacker: number; dmgDoneByDefender: number };\r\n}\r\nexport const hasOnMinionKilled = (card: Card): card is OnMinionKilledCard =>\r\n\t(card as OnMinionKilledCard)?.onMinionKilled !== undefined;\r\n\r\nexport interface OnBeforeMagnetizeCard extends Card {\r\n\tonBeforeMagnetize(entity: BoardEntity | BoardTrinket, input: OnBeforeMagnetizeInput): void;\r\n}\r\nexport const hasOnBeforeMagnetize = (card: Card): card is OnBeforeMagnetizeCard =>\r\n\t(card as OnBeforeMagnetizeCard)?.onBeforeMagnetize !== undefined;\r\n\r\nexport interface OnBeforeMagnetizeSelfCard extends Card {\r\n\tonBeforeMagnetizeSelf(entity: BoardEntity, input: OnBeforeMagnetizeSelfInput): void;\r\n}\r\nexport const hasOnBeforeMagnetizeSelf = (card: Card): card is OnBeforeMagnetizeSelfCard =>\r\n\t(card as OnBeforeMagnetizeSelfCard)?.onBeforeMagnetizeSelf !== undefined;\r\n\r\nexport interface OnAfterMagnetizeToSelfCard extends Card {\r\n\tonAfterMagnetizeToSelf(entity: BoardEntity, input: OnAfterMagnetizeSelfInput): void;\r\n}\r\nexport const hasOnAfterMagnetizeToSelf = (card: Card): card is OnAfterMagnetizeToSelfCard =>\r\n\t(card as OnAfterMagnetizeToSelfCard)?.onAfterMagnetizeToSelf !== undefined;\r\n\r\nexport interface OnAfterMagnetizeSelfCard extends Card {\r\n\tonAfterMagnetizeSelf(entity: BoardEntity, input: OnAfterMagnetizeInput): void;\r\n}\r\nexport const hasOnAfterMagnetizeSelf = (card: Card): card is OnAfterMagnetizeSelfCard =>\r\n\t(card as OnAfterMagnetizeSelfCard)?.onAfterMagnetizeSelf !== undefined;\r\n\r\nexport interface OnAfterMagnetizeCard extends Card {\r\n\tonAfterMagnetize(entity: BoardEntity | BoardTrinket, input: OnAfterMagnetizeInput): void;\r\n}\r\nexport const hasOnAfterMagnetize = (card: Card): card is OnAfterMagnetizeCard =>\r\n\t(card as OnAfterMagnetizeCard)?.onAfterMagnetize !== undefined;\r\n\r\nexport interface OnSpawnFailCard extends Card {\r\n\tonSpawnFail(entity: BoardEntity, input: OnSpawnFailInput): void;\r\n}\r\nexport const hasOnSpawnFail = (card: Card): card is OnSpawnFailCard =>\r\n\t(card as OnSpawnFailCard)?.onSpawnFail !== undefined;\r\n\r\nexport interface PlayedBloodGemsOnMeCard extends Card {\r\n\tplayedBloodGemsOnMe(entity: BoardEntity, input: PlayedBloodGemsOnMeInput): void;\r\n}\r\nexport const hasPlayedBloodGemsOnMe = (card: Card): card is PlayedBloodGemsOnMeCard =>\r\n\t(card as PlayedBloodGemsOnMeCard)?.playedBloodGemsOnMe !== undefined;\r\n\r\nexport interface PlayedBloodGemsOnAnyCard extends Card {\r\n\tplayedBloodGemsOnAny(entity: BoardEntity, input: PlayedBloodGemsOnAnyInput): void;\r\n}\r\nexport const hasPlayedBloodGemsOnAny = (card: Card): card is PlayedBloodGemsOnAnyCard =>\r\n\t(card as PlayedBloodGemsOnAnyCard)?.playedBloodGemsOnAny !== undefined;\r\n\r\nexport interface OnGlobalInfoUpdatedCard extends Card {\r\n\tonGlobalInfoUpdated(entity: BoardEntity, input: OnGlobalInfoUpdatedInput): void;\r\n}\r\nexport const hasOnGlobalInfoUpdated = (card: Card): card is OnGlobalInfoUpdatedCard =>\r\n\t(card as OnGlobalInfoUpdatedCard)?.onGlobalInfoUpdated !== undefined;\r\n\r\nexport interface OnGlobalInfoUpdatedEnchantmentCard extends Card {\r\n\tonGlobalInfoUpdatedEnchantment(\r\n\t\tentity: BoardEntity,\r\n\t\tenchantment: BoardEnchantment,\r\n\t\tinput: OnGlobalInfoUpdatedInput,\r\n\t): void;\r\n}\r\nexport const hasOnGlobalInfoUpdatedEnchantment = (card: Card): card is OnGlobalInfoUpdatedEnchantmentCard =>\r\n\t(card as OnGlobalInfoUpdatedEnchantmentCard)?.onGlobalInfoUpdatedEnchantment !== undefined;\r\n\r\nexport interface OnGildedCard extends Card {\r\n\tonGilded(entity: BoardEntity, input: OnGildedInput): void;\r\n}\r\nexport const hasOnGilded = (card: Card): card is OnGildedCard => (card as OnGildedCard)?.onGilded !== undefined;\r\n\r\nexport interface OnSpawnFailInput {\r\n\tfailedSpawn: BoardEntity;\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n}\r\n\r\nexport interface DeityAwakenInput {\r\n\thero: BgsPlayerEntity;\r\n\tboard: BoardEntity[];\r\n\totherHero: BgsPlayerEntity;\r\n\totherBoard: BoardEntity[];\r\n\tgameState: FullGameState;\r\n}\r\n\r\nexport interface DiscardInput {\r\n\tdiscarded: BoardEntity;\r\n\thero: BgsPlayerEntity;\r\n\tboard: BoardEntity[];\r\n\totherHero: BgsPlayerEntity;\r\n\totherBoard: BoardEntity[];\r\n\tgameState: FullGameState;\r\n}\r\n\r\nexport interface CastSpellInput {\r\n\tspellCardId: string;\r\n\tsource: BoardEntity | BoardTrinket | BgsPlayerEntity;\r\n\ttarget: BoardEntity;\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherBoard: BoardEntity[];\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n}\r\nexport interface OnDamagedInput {\r\n\tdamagedEntity: BoardEntity;\r\n\tdamageDealer: BoardEntity | BgsPlayerEntity;\r\n\tdamage: number;\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n}\r\n"]}
@@ -7,7 +7,7 @@ exports.FragrantPhylacteryEnchantment = {
7
7
  deathrattleSpawnEnchantmentEffect: (enchantment, minion, input) => {
8
8
  const targets = input.boardWithDeadEntity.filter((e) => e.health > 0 && !e.definitelyDead && e !== enchantment && e !== minion);
9
9
  for (const target of targets) {
10
- (0, stats_1.modifyStats)(target, input.deadEntity, input.deadEntity.attack, input.deadEntity.maxHealth, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.gameState);
10
+ (0, stats_1.modifyStats)(target, input.deadEntity, input.deadEntity.maxAttack, input.deadEntity.maxHealth, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.gameState);
11
11
  }
12
12
  return null;
13
13
  },
@@ -1 +1 @@
1
- {"version":3,"file":"fragrant-phylactery-enchantment.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/fragrant-phylactery-enchantment.ts"],"names":[],"mappings":";;;AAGA,qDAAwD;AAG3C,QAAA,6BAA6B,GAAoC;IAC7E,OAAO,EAAE,mBAAmE;IAC5E,iCAAiC,EAAE,CAClC,WAA0E,EAC1E,MAAsC,EACtC,KAAgC,EAC/B,EAAE;QAGH,MAAM,OAAO,GAAG,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,MAAM,CAC7E,CAAC;QACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC7B,IAAA,mBAAW,EACV,MAAM,EACN,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,UAAU,CAAC,MAAM,EACvB,KAAK,CAAC,UAAU,CAAC,SAAS,EAC1B,KAAK,CAAC,mBAAmB,EACzB,KAAK,CAAC,uBAAuB,EAC7B,KAAK,CAAC,SAAS,CACf,CAAC;SACF;QACD,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { DeathrattleTriggeredInput } from '../../../simulation/deathrattle-on-trigger';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { DeathrattleSpawnEnchantmentCard } from '../../card.interface';\r\n\r\nexport const FragrantPhylacteryEnchantment: DeathrattleSpawnEnchantmentCard = {\r\n\tcardIds: [CardIds.TamsinRoame_ImpendingSacrificeEnchantment_BG20_HERO_282e2],\r\n\tdeathrattleSpawnEnchantmentEffect: (\r\n\t\tenchantment: { cardId: string; originEntityId?: number; repeats?: number },\r\n\t\tminion: BoardEntity | null | undefined,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t) => {\r\n\t\t// Doesn't resurrect dead minions\r\n\t\t// 33.4 https://replays.firestoneapp.com/?reviewId=44c91f87-17a0-462c-8f24-3002cbcd42d5&turn=21&action=1\r\n\t\tconst targets = input.boardWithDeadEntity.filter(\r\n\t\t\t(e) => e.health > 0 && !e.definitelyDead && e !== enchantment && e !== minion,\r\n\t\t);\r\n\t\tfor (const target of targets) {\r\n\t\t\tmodifyStats(\r\n\t\t\t\ttarget,\r\n\t\t\t\tinput.deadEntity,\r\n\t\t\t\tinput.deadEntity.attack,\r\n\t\t\t\tinput.deadEntity.maxHealth,\r\n\t\t\t\tinput.boardWithDeadEntity,\r\n\t\t\t\tinput.boardWithDeadEntityHero,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\treturn null;\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"fragrant-phylactery-enchantment.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/fragrant-phylactery-enchantment.ts"],"names":[],"mappings":";;;AAGA,qDAAwD;AAG3C,QAAA,6BAA6B,GAAoC;IAC7E,OAAO,EAAE,mBAAmE;IAC5E,iCAAiC,EAAE,CAClC,WAA0E,EAC1E,MAAsC,EACtC,KAAgC,EAC/B,EAAE;QAGH,MAAM,OAAO,GAAG,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,MAAM,CAC7E,CAAC;QACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC7B,IAAA,mBAAW,EACV,MAAM,EACN,KAAK,CAAC,UAAU,EAEhB,KAAK,CAAC,UAAU,CAAC,SAAS,EAC1B,KAAK,CAAC,UAAU,CAAC,SAAS,EAC1B,KAAK,CAAC,mBAAmB,EACzB,KAAK,CAAC,uBAAuB,EAC7B,KAAK,CAAC,SAAS,CACf,CAAC;SACF;QACD,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { DeathrattleTriggeredInput } from '../../../simulation/deathrattle-on-trigger';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { DeathrattleSpawnEnchantmentCard } from '../../card.interface';\r\n\r\nexport const FragrantPhylacteryEnchantment: DeathrattleSpawnEnchantmentCard = {\r\n\tcardIds: [CardIds.TamsinRoame_ImpendingSacrificeEnchantment_BG20_HERO_282e2],\r\n\tdeathrattleSpawnEnchantmentEffect: (\r\n\t\tenchantment: { cardId: string; originEntityId?: number; repeats?: number },\r\n\t\tminion: BoardEntity | null | undefined,\r\n\t\tinput: DeathrattleTriggeredInput,\r\n\t) => {\r\n\t\t// Doesn't resurrect dead minions\r\n\t\t// 33.4 https://replays.firestoneapp.com/?reviewId=44c91f87-17a0-462c-8f24-3002cbcd42d5&turn=21&action=1\r\n\t\tconst targets = input.boardWithDeadEntity.filter(\r\n\t\t\t(e) => e.health > 0 && !e.definitelyDead && e !== enchantment && e !== minion,\r\n\t\t);\r\n\t\tfor (const target of targets) {\r\n\t\t\tmodifyStats(\r\n\t\t\t\ttarget,\r\n\t\t\t\tinput.deadEntity,\r\n\t\t\t\t// So that it's not affected by the removeAura stuff\r\n\t\t\t\tinput.deadEntity.maxAttack,\r\n\t\t\t\tinput.deadEntity.maxHealth,\r\n\t\t\t\tinput.boardWithDeadEntity,\r\n\t\t\t\tinput.boardWithDeadEntityHero,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\treturn null;\r\n\t},\r\n};\r\n"]}
@@ -17,11 +17,13 @@ exports.HeroicBroodmother = {
17
17
  break;
18
18
  }
19
19
  minion.attackImmediately = true;
20
- (0, attack_1.simulateAttack)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState);
20
+ (0, attack_1.simulateAttack)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState, {
21
+ skipSummonWhenSpace: true,
22
+ });
21
23
  minion.attackImmediately = false;
22
24
  minion.hasAttacked = previousHasAttacked;
23
25
  }
24
- return { hasTriggered: true, shouldRecomputeCurrentAttacker: true };
26
+ return { hasTriggered: true, shouldRecomputeCurrentAttacker: true, skipSummonsWhenSpace: true };
25
27
  },
26
28
  };
27
29
  //# sourceMappingURL=heroic-broodmother.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"heroic-broodmother.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/heroic-broodmother.ts"],"names":[],"mappings":";;;AAQA,mEAAqE;AACrE,uDAA4D;AAM/C,QAAA,iBAAiB,GAAkC;IAC/D,OAAO,EAAE,0BAA0E;IACnF,KAAK,EAAE,CAAC,MAAmB,EAAE,KAAoB,EAAE,EAAE;QACpD,IAAA,kCAAkB,EAAC,MAAM,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAClH,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IACD,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;QACvD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,iBAAyC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,mBAAmB,GAAG,MAAM,CAAC,WAAW,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE;YACjC,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;gBAC/E,MAAM;aACN;YACD,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAChC,IAAA,uBAAc,EACb,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;YACF,MAAM,CAAC,iBAAiB,GAAG,KAAK,CAAC;YACjC,MAAM,CAAC,WAAW,GAAG,mBAAmB,CAAC;SACzC;QACD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,CAAC;IACrE,CAAC;CACD,CAAC","sourcesContent":["/**\r\n * Heroic Broodmother (Tier 6, 7/7)\r\n * Rally: Gain Divine Shield. Start of Combat: Attack immediately.\r\n *\r\n * Golden Heroic Broodmother (Tier 6, 14/14)\r\n * Rally: Gain Divine Shield. Start of Combat: Attack immediately twice.\r\n */\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { updateDivineShield } from '../../../keywords/divine-shield';\r\nimport { simulateAttack } from '../../../simulation/attack';\r\nimport { OnAttackInput } from '../../../simulation/on-attack';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { RallyCard, StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const HeroicBroodmother: RallyCard & StartOfCombatCard = {\r\n\tcardIds: [CardIds.HeroicBroodmother_BG36_849, CardIds.HeroicBroodmother_BG36_849_G],\r\n\trally: (minion: BoardEntity, input: OnAttackInput) => {\r\n\t\tupdateDivineShield(minion, input.attackingBoard, input.attackingHero, input.defendingHero, true, input.gameState);\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n\tstartOfCombat: (minion: BoardEntity, input: SoCInput) => {\r\n\t\tconst attacks = minion.cardId === CardIds.HeroicBroodmother_BG36_849_G ? 2 : 1;\r\n\t\tconst previousHasAttacked = minion.hasAttacked;\r\n\t\tfor (let i = 0; i < attacks; i++) {\r\n\t\t\tif (minion.health <= 0 || minion.definitelyDead || !input.opponentBoard.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tminion.attackImmediately = true;\r\n\t\t\tsimulateAttack(\r\n\t\t\t\tinput.playerBoard,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tinput.opponentBoard,\r\n\t\t\t\tinput.opponentEntity,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t\tminion.attackImmediately = false;\r\n\t\t\tminion.hasAttacked = previousHasAttacked;\r\n\t\t}\r\n\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true };\r\n\t},\r\n};\r\n"]}
1
+ {"version":3,"file":"heroic-broodmother.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/heroic-broodmother.ts"],"names":[],"mappings":";;;AAQA,mEAAqE;AAErE,uDAA4D;AAK/C,QAAA,iBAAiB,GAAkC;IAC/D,OAAO,EAAE,0BAA0E;IACnF,KAAK,EAAE,CAAC,MAAmB,EAAE,KAAoB,EAAE,EAAE;QACpD,IAAA,kCAAkB,EACjB,MAAM,EACN,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,aAAa,EACnB,IAAI,EACJ,KAAK,CAAC,SAAS,CACf,CAAC;QACF,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IACD,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;QACvD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,iBAAyC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,mBAAmB,GAAG,MAAM,CAAC,WAAW,CAAC;QAC/C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE;YACjC,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;gBAC/E,MAAM;aACN;YACD,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAChC,IAAA,uBAAc,EACb,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EACf;gBACC,mBAAmB,EAAE,IAAI;aACzB,CACD,CAAC;YACF,MAAM,CAAC,iBAAiB,GAAG,KAAK,CAAC;YACjC,MAAM,CAAC,WAAW,GAAG,mBAAmB,CAAC;SACzC;QACD,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,8BAA8B,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;IACjG,CAAC;CACD,CAAC","sourcesContent":["/**\r\n * Heroic Broodmother (Tier 6, 7/7)\r\n * Rally: Gain Divine Shield. Start of Combat: Attack immediately.\r\n *\r\n * Golden Heroic Broodmother (Tier 6, 14/14)\r\n * Rally: Gain Divine Shield. Start of Combat: Attack immediately twice.\r\n */\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { updateDivineShield } from '../../../keywords/divine-shield';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { simulateAttack } from '../../../simulation/attack';\r\nimport { OnAttackInput } from '../../../simulation/on-attack';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { RallyCard, StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const HeroicBroodmother: RallyCard & StartOfCombatCard = {\r\n\tcardIds: [CardIds.HeroicBroodmother_BG36_849, CardIds.HeroicBroodmother_BG36_849_G],\r\n\trally: (minion: BoardEntity, input: OnAttackInput) => {\r\n\t\tupdateDivineShield(\r\n\t\t\tminion,\r\n\t\t\tinput.attackingBoard,\r\n\t\t\tinput.attackingHero,\r\n\t\t\tinput.defendingHero,\r\n\t\t\ttrue,\r\n\t\t\tinput.gameState,\r\n\t\t);\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n\tstartOfCombat: (minion: BoardEntity, input: SoCInput) => {\r\n\t\tconst attacks = minion.cardId === CardIds.HeroicBroodmother_BG36_849_G ? 2 : 1;\r\n\t\tconst previousHasAttacked = minion.hasAttacked;\r\n\t\tfor (let i = 0; i < attacks; i++) {\r\n\t\t\tif (minion.health <= 0 || minion.definitelyDead || !input.opponentBoard.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tminion.attackImmediately = true;\r\n\t\t\tsimulateAttack(\r\n\t\t\t\tinput.playerBoard,\r\n\t\t\t\tinput.playerEntity,\r\n\t\t\t\tinput.opponentBoard,\r\n\t\t\t\tinput.opponentEntity,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t\t{\r\n\t\t\t\t\tskipSummonWhenSpace: true,\r\n\t\t\t\t},\r\n\t\t\t);\r\n\t\t\tminion.attackImmediately = false;\r\n\t\t\tminion.hasAttacked = previousHasAttacked;\r\n\t\t}\r\n\t\treturn { hasTriggered: true, shouldRecomputeCurrentAttacker: true, skipSummonsWhenSpace: true };\r\n\t},\r\n};\r\n"]}
@@ -27,7 +27,7 @@ const simulateAttack = (attackingBoard, attackingBoardHero, defendingBoard, defe
27
27
  if (attackingBoard.length === 0 || defendingBoard.length === 0) {
28
28
  return;
29
29
  }
30
- const attackingEntity = getAttackingEntity(attackingBoard, gameState.allCards);
30
+ const attackingEntity = getAttackingEntity(attackingBoard, attackingBoardHero, gameState.allCards);
31
31
  if (attackingEntity) {
32
32
  gameState.sharedState.currentAttackerEntityId = attackingEntity.entityId;
33
33
  const attackingEntityIndex = attackingBoard.indexOf(attackingEntity);
@@ -35,6 +35,7 @@ const simulateAttack = (attackingBoard, attackingBoardHero, defendingBoard, defe
35
35
  const isAttackingImmediately = attackingEntity.attackImmediately;
36
36
  if (!isAttackingImmediately) {
37
37
  attackingEntitiesToTheLeft.forEach((entity) => (entity.hasAttacked = 2));
38
+ attackingBoardHero.leftMostAttacked = 2;
38
39
  }
39
40
  else {
40
41
  attackingEntity.attackImmediately = false;
@@ -56,6 +57,7 @@ const simulateAttack = (attackingBoard, attackingBoardHero, defendingBoard, defe
56
57
  }
57
58
  gameState.sharedState.currentAttackerEntityId = null;
58
59
  attackingEntity.hasAttacked = 1;
60
+ attackingBoardHero.leftMostAttacked = 1;
59
61
  }
60
62
  return attackingEntity;
61
63
  };
@@ -149,7 +151,7 @@ const performAttack = (attackingEntity, defendingEntity, attackingBoard, attacki
149
151
  }
150
152
  return { damageDoneByAttacker, damageDoneByDefender };
151
153
  };
152
- const getAttackingEntity = (attackingBoard, allCards) => {
154
+ const getAttackingEntity = (attackingBoard, attackingBoardHero, allCards) => {
153
155
  let validAttackers = attackingBoard.filter((entity) => (0, entity_utils_1.canAttack)(entity));
154
156
  if (validAttackers.length === 0) {
155
157
  return null;
@@ -159,6 +161,7 @@ const getAttackingEntity = (attackingBoard, allCards) => {
159
161
  }
160
162
  else if (validAttackers.every((e) => e.hasAttacked != null)) {
161
163
  attackingBoard.forEach((e) => (e.hasAttacked = undefined));
164
+ attackingBoardHero.leftMostAttacked = undefined;
162
165
  }
163
166
  else {
164
167
  validAttackers = validAttackers.filter((entity) => entity.hasAttacked == undefined);
@@ -1 +1 @@
1
- {"version":3,"file":"attack.js","sourceRoot":"","sources":["../../src/simulation/attack.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnAfterDeath, hasOnDeath } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { debugState } from '../debug-state';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { updateVenomous } from '../keywords/venomous';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { groupByFunction, pickRandom } from '../services/utils';\r\nimport { addImpliedMechanics, isBoardEntity, isFish } from '../utils';\r\nimport { applyAfterAttackEffects, applyAfterAttackTrinkets } from './after-attack';\r\nimport { onEntityDamaged } from './damage-effects';\r\nimport { rememberDeathrattles } from './deathrattle-effects';\r\nimport { orchestrateMinionDeathEffects } from './deathrattle-orchestration';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { makeMinionsDie } from './minion-death';\r\nimport { onMinionKill } from './minion-kill';\r\nimport { applyOnAttackEffects } from './on-attack';\r\nimport { applyOnBeingAttackedBuffs } from './on-being-attacked';\r\nimport { resolvePendingEffects } from './pending-effects';\r\nimport { performEntitySpawns } from './spawns';\r\nimport { applyAfterStatsUpdate } from './stats';\r\nimport { handleSummonsWhenSpace } from './summon-when-space';\r\nimport { canAttack } from './utils/entity-utils';\r\n\r\n// Only use it to simulate actual attack. To simulate damage, or something similar, use bumpInto\r\nexport const simulateAttack = (\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t\tforceTarget?: BoardEntity;\r\n\t},\r\n): BoardEntity => {\r\n\t// console.debug(\r\n\t// \t'\\nsimulating attack',\r\n\t// \tstringifySimple(attackingBoard, gameState.allCards),\r\n\t// \t'\\n',\r\n\t// \tstringifySimple(defendingBoard, gameState.allCards),\r\n\t// );\r\n\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst attackingEntity = getAttackingEntity(attackingBoard, gameState.allCards);\r\n\tif (attackingEntity) {\r\n\t\tgameState.sharedState.currentAttackerEntityId = attackingEntity.entityId;\r\n\t\t// Get the left entities now, otherwise things might break if the attacker dies and/or other\r\n\t\t// entities pop\r\n\t\tconst attackingEntityIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\tconst attackingEntitiesToTheLeft = attackingBoard.slice(0, attackingEntityIndex);\r\n\t\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\t\t// In case of Broodmother spawn, it spawns where the dead minion was, and has no influence on the\r\n\t\t// attack order\r\n\t\t// Situation this is trying to resolve by putting this right at the top of the loop:\r\n\t\t// - One scallywag attacks into another one, both die\r\n\t\t// - The first one attacks. To its left is a Harmless Bonehead with 1 HP. The scallywag attacks, and both scallys die\r\n\t\t// - The *other* sky pirate attacks first, and kills the bonehead. Two minions are spawned\r\n\t\t// - The first sy pirate attacks\r\n\t\t// - The initial loop is resolved. If this is at the end, the Harmless Bonehead is already dead, and not flagged\r\n\t\t// While having this right away, we immediately flag all minions to the left\r\n\t\tif (!isAttackingImmediately) {\r\n\t\t\t// Make sure they won't be able to attack until everyone has attacked\r\n\t\t\t// See http://replays.firestoneapp.com/?reviewId=a1b3066d-e806-44c1-ab4b-7ef9dbf9b5b9&turn=5&action=4\r\n\t\t\tattackingEntitiesToTheLeft.forEach((entity) => (entity.hasAttacked = 2));\r\n\t\t} else {\r\n\t\t\t// Change it right away so that new spawns don't trigger the \"attack immediately\" again\r\n\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t}\r\n\r\n\t\tconst numberOfAttacks = attackingEntity.windfury ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfAttacks; i++) {\r\n\t\t\t// We refresh the entity in case of windfury\r\n\t\t\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\t\t\t// We still want to flag the entity as having attacked, so that it doesn't attack again\r\n\t\t\t\t// after teammate switch in Duos\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t// Check that didn't die\r\n\t\t\tif (attackingBoard.find((entity) => entity.entityId === attackingEntity.entityId)) {\r\n\t\t\t\tconst defendingEntity: BoardEntity =\r\n\t\t\t\t\toptions?.forceTarget ?? getDefendingEntity(defendingBoard, attackingEntity);\r\n\t\t\t\t// Can happen with a single defender that has stealth\r\n\t\t\t\tif (defendingEntity && defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tdoFullAttack(\r\n\t\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t\toptions,\r\n\t\t\t\t\t);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Solves the edge case of Sky Pirate vs a stealth board\r\n\t\t\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tgameState.sharedState.currentAttackerEntityId = null;\r\n\t\tattackingEntity.hasAttacked = 1;\r\n\t}\r\n\treturn attackingEntity;\r\n};\r\n\r\nexport const doFullAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t},\r\n) => {\r\n\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\tgameState.spectator.registerAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tdefendingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoardHero,\r\n\t);\r\n\t// http://replays.firestoneapp.com/?reviewId=50576a9f-2e6a-4600-87ba-6e737ca9853e&turn=21&action=4\r\n\t// Looks like onBeingAttacked effects apply before onAttack effects\r\n\tapplyOnBeingAttackedBuffs(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker1, damageDoneByDefender: damageDoneByDefender1 } =\r\n\t\tapplyOnAttackEffects(\r\n\t\t\tattackingEntity,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker2, damageDoneByDefender: damageDoneByDefender2 } = performAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst damageDoneByAttacker = damageDoneByAttacker1 + damageDoneByAttacker2;\r\n\tconst damageDoneByDefender = damageDoneByDefender1 + damageDoneByDefender2;\r\n\r\n\t// Process this after the minions die and deathrattles are triggered/spawned\r\n\t// https://replays.firestoneapp.com/?reviewId=dd4e9dbe-abca-434a-ab94-04777cbedefe&turn=29&action=3\r\n\t// BUT: the attacking entity's afterAttack (like Macaw) needs to be processed\r\n\t// To recap:\r\n\t// - Jar o'Gems procs after the deathrattles have spawned\r\n\t// - When Monstrous Macaw procs a deathrattle, it is still on board, thus limiting the spawn room\r\n\t// So not sure what the exact timings are. It could be:\r\n\t// 1. Trigger minion's after attack\r\n\t// 2. Make minions die\r\n\t// 3. Process trinkets after attack\r\n\t// I have asked on Discord - for now I will consider a \"minion after attack\" phase and a \"trinket after attack\" phase.\r\n\t// I'm not sure about the secrets / trinkets, they will need to be adapted\r\n\t// The \"minion after attack\" phase seems to happen before the minions die:\r\n\t// https://replays.firestoneapp.com/?reviewId=ecdfab8d-e20e-4264-be4b-9cbe754118f7&turn=29&action=14\r\n\t// Here the Rally + Deathrattle minion attacks, but Deathstrider procs before it dies\r\n\tapplyAfterAttackEffects(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\r\n\tprocessMinionDeath(\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t\toptions?.skipSummonWhenSpace || isAttackingImmediately,\r\n\t);\r\n\r\n\tapplyAfterAttackTrinkets(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tattackingEntity.immuneWhenAttackCharges = Math.max(0, (attackingEntity.immuneWhenAttackCharges ?? 0) - 1);\r\n\t// if (\r\n\t// \tdefendingEntity.health > 0 &&\r\n\t// \t!defendingEntity.definitelyDead\r\n\t// \t&& (defendingEntity.cardId === CardIds.YoHoOgre_BGS_060 ||\r\n\t// \t\tdefendingEntity.cardId === CardIds.YoHoOgre_TB_BaconUps_150)\r\n\t// ) {\r\n\t// \tdefendingEntity.attackImmediately = true;\r\n\t// \tif (defendingEntity.attackImmediately) {\r\n\t// \t\tsimulateAttack(defendingBoard, defendingBoardHero, attackingBoard, attackingBoardHero, gameState);\r\n\t// \t}\r\n\t// }\r\n};\r\n\r\nconst performAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): { damageDoneByAttacker: number; damageDoneByDefender: number } => {\r\n\tlet damageDoneByAttacker = 0;\r\n\tlet damageDoneByDefender = 0;\r\n\tconst hadVenomous = attackingEntity.venomous;\r\n\r\n\tif ([CardIds.BabyKrush_BG22_001, CardIds.BabyKrush_BG22_001_G].includes(attackingEntity.cardId as CardIds)) {\r\n\t\tconst spawns = spawnEntities(\r\n\t\t\tattackingEntity.cardId === CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t? CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t: CardIds.BabyKrush_DevilsaurToken,\r\n\t\t\t1,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t\ttrue,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t\tif (spawns.length > 0) {\r\n\t\t\tconst sourceIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\t\tspawns,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tsourceIndex,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tfor (const actualSpawn of actualSpawns) {\r\n\t\t\t\tif (defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tperformAttack(\r\n\t\t\t\t\t\tactualSpawn,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// For Prestor\r\n\tconst defenderAliveBeforeAttack = defendingEntity.health > 0 && !defendingEntity.definitelyDead;\r\n\t// Because of Bristleback Knight, which changes its divine shield status during bumpEntities\r\n\tconst attackerHadDivineShield = attackingEntity.divineShield;\r\n\tconst defenderHadDivineShield = defendingEntity.divineShield;\r\n\t// For cleave\r\n\t// We do that now so that we don't include entities that spawn on entity damaged\r\n\tconst defenderNeighbours: readonly BoardEntity[] = getNeighbours(defendingBoard, defendingEntity);\r\n\tif (defenderAliveBeforeAttack) {\r\n\t\tif (!attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\t// TODO: this bumpEntities approach doesn't work well, as it leads to code duplication\r\n\t\t\tdamageDoneByDefender += bumpEntities(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tdamageDoneByAttacker += bumpEntities(\r\n\t\t\tdefendingEntity,\r\n\t\t\tattackingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tif (defendingEntity.attack > 0 && attackerHadDivineShield && !attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (attackingEntity.attack > 0 && defenderHadDivineShield) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// This whole logic is a MEEEEESSSSSSSSSSSSSSS\r\n\t\tif (damageDoneByDefender > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdamageDoneByDefender,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (damageDoneByAttacker > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdamageDoneByAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tif (defendingEntity.health <= 0 || defendingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\thadVenomous,\r\n\t\t\t\ttrue,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t\tif (attackingEntity.health <= 0 || attackingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t}\r\n\t// Cleave\r\n\tif (attackingEntity.cleave) {\r\n\t\tfor (const neighbour of defenderNeighbours) {\r\n\t\t\tconst thisAttackDamage = bumpEntities(\r\n\t\t\t\tneighbour,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\ttrue,\r\n\t\t\t\thadVenomous,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += thisAttackDamage;\r\n\t\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t\t// cause wrong results to happen\r\n\t\t\tif (attackingEntity.attack > 0 && neighbour.divineShield) {\r\n\t\t\t\tupdateDivineShield(neighbour, defendingBoard, defendingBoardHero, attackingBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (thisAttackDamage > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\tthisAttackDamage,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tif (neighbour.health <= 0 || neighbour.definitelyDead) {\r\n\t\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\thadVenomous,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tdefenderNeighbours,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tattackingEntity.attackImmediately = false;\r\n\tif (attackingEntity.enchantments.some((e) => e.cardId === CardIds.VolatileVenom_VolatileEnchantment)) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t}\r\n\treturn { damageDoneByAttacker, damageDoneByDefender };\r\n};\r\n\r\n// TODO: Could it be possible to store the index of the entity that last attacked? Probably not, because minion\r\n// spawns would mess this up? Could we update the indexes as each entity spawns / dies?\r\nconst getAttackingEntity = (attackingBoard: BoardEntity[], allCards: AllCardsService): BoardEntity => {\r\n\tlet validAttackers = attackingBoard.filter((entity) => canAttack(entity));\r\n\tif (validAttackers.length === 0) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tif (validAttackers.some((entity) => entity.attackImmediately)) {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.attackImmediately);\r\n\t} else if (validAttackers.every((e) => e.hasAttacked != null)) {\r\n\t\tattackingBoard.forEach((e) => (e.hasAttacked = undefined));\r\n\t} else {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.hasAttacked == undefined);\r\n\t}\r\n\tconst attacker = validAttackers[0];\r\n\treturn attacker;\r\n};\r\n\r\nexport const findNearestEnemies = (\r\n\tattackingBoard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tentityIndexFromRight: number,\r\n\tdefendingBoard: BoardEntity[],\r\n\tnumberOfTargets: number,\r\n\tallCards: AllCardsService,\r\n): BoardEntity[] => {\r\n\tconst result = [];\r\n\tif (defendingBoard.length > 0) {\r\n\t\t// console.debug('defending board', numberOfTargets, stringifySimple(defendingBoard, allCards));\r\n\t\tconst attackerIndex = attackingBoard.length - entityIndexFromRight - 1;\r\n\t\tconst targetIndex = attackerIndex - (attackingBoard.length - defendingBoard.length) / 2;\r\n\t\t// console.debug('indexes', attackerIndex, entityIndexFromRight, targetIndex, attackingBoard.length);\r\n\r\n\t\tfor (let i = 0; i < numberOfTargets; i++) {\r\n\t\t\tconst possibleTargets = defendingBoard\r\n\t\t\t\t.filter((e) => !e.definitelyDead && e.health > 0)\r\n\t\t\t\t.filter((e) => !result.includes(e));\r\n\t\t\t// console.debug('possibleTargets', stringifySimple(possibleTargets, allCards));\r\n\t\t\tif (!possibleTargets.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tconst targetGroups = groupByFunction((e: BoardEntity) => Math.abs(defendingBoard.indexOf(e) - targetIndex))(\r\n\t\t\t\tpossibleTargets,\r\n\t\t\t);\r\n\t\t\tconst distances = Object.keys(targetGroups)\r\n\t\t\t\t.map((k) => +k)\r\n\t\t\t\t.sort();\r\n\t\t\tconst nearestDistance = distances[0];\r\n\t\t\tif (nearestDistance != null) {\r\n\t\t\t\t// console.debug(\r\n\t\t\t\t// \t'targetGroups[nearestDistance]',\r\n\t\t\t\t// \tnearestDistance,\r\n\t\t\t\t// \tstringifySimple(targetGroups[nearestDistance], allCards),\r\n\t\t\t\t// );\r\n\t\t\t\tconst target = pickRandom(targetGroups[nearestDistance]);\r\n\t\t\t\tresult.push(target);\r\n\t\t\t}\r\n\t\t\t// console.debug('\\n');\r\n\t\t}\r\n\t}\r\n\treturn result.filter((e) => !!e);\r\n};\r\n\r\nexport const getNeighbours = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n\talwaysIncludeBoth = false,\r\n): readonly BoardEntity[] => {\r\n\tconst neighbours = [];\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\tneighbours.push(leftNeighbour);\r\n\t\t}\r\n\r\n\t\t// If the deadEntityIndexFromRight === 0 (right-most minion), no neighbour will be found\r\n\t\tconst rightNeighbourIndex = board.length - 1 - (deadEntityIndexFromRight - 1);\r\n\t\tconst rightNeighbour = board[rightNeighbourIndex];\r\n\t\tif (rightNeighbour) {\r\n\t\t\tneighbours.push(rightNeighbour);\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\tneighbours.push(board[index - 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t\t// neighbours.push(entity);\r\n\t\tif (index + 1 < board.length) {\r\n\t\t\tneighbours.push(board[index + 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t}\r\n\treturn neighbours;\r\n};\r\n\r\nexport const getLeftNeighbour = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n): BoardEntity => {\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\treturn leftNeighbour;\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\treturn board[index - 1];\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const dealDamageToRandomEnemy = (\r\n\tboardToBeDamaged: BoardEntity[],\r\n\tboardToBeDamagedHero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity,\r\n\tdamage: number,\r\n\tboardWithAttackOrigin: BoardEntity[],\r\n\tboardWithAttackOriginHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (boardToBeDamaged.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\tconst validTargets = boardToBeDamaged.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst defendingEntity: BoardEntity = pickRandom(validTargets);\r\n\tif (defendingEntity) {\r\n\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\tdamageSource,\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t);\r\n\t\tdealDamageToMinion(\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tdamageSource,\r\n\t\t\tdamage,\r\n\t\t\tboardWithAttackOrigin,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n};\r\n\r\nexport const dealDamageToMinion = (\r\n\ttarget: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!target) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst isDeadBeforeDamage = target.definitelyDead || target.health <= 0;\r\n\tconst hadVenomous = (damageSource as BoardEntity).venomous;\r\n\tconst spawns = [];\r\n\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t// without it\r\n\tconst fakeAttacker = {\r\n\t\t...(damageSource || {}),\r\n\t\tentityId: -1,\r\n\t\tattack: damage,\r\n\t\t// attacking: true,\r\n\t} as BoardEntity;\r\n\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\r\n\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t// cause wrong results to happen\r\n\t// TODO: why isn't it done in bumpEntities?\r\n\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t// the divine shield once both bumps are done\r\n\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t}\r\n\r\n\tif (actualDamageDone > 0) {\r\n\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\ttarget,\r\n\t\t\tboard,\r\n\t\t\thero,\r\n\t\t\totherBoard,\r\n\t\t\totherHero,\r\n\t\t\tdamageSource,\r\n\t\t\tactualDamageDone,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\tonMinionKill(\r\n\t\t\t\tdamageSource as BoardEntity,\r\n\t\t\t\thadVenomous,\r\n\t\t\t\tfalse,\r\n\t\t\t\ttarget,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\t[],\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\tif (actualDamageDone > 0) {\r\n\t\tif (isBoardEntity(damageSource)) {\r\n\t\t\tdamageSource.venomous = false;\r\n\t\t}\r\n\t}\r\n\tconst defendingEntityIndex = board.findIndex((entity) => entity.entityId === target.entityId);\r\n\tboard[defendingEntityIndex] = target;\r\n\treturn actualDamageDone;\r\n};\r\n\r\n// Because the \"onEntityDamaged\" effect is only called once all the minions are damaged\r\nexport const dealDamageToMinions = (\r\n\ttargets: BoardEntity[],\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!targets?.length) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst actualDamagesDone = [];\r\n\tconst areDeadBeforeDamage = targets.map((target) => target.definitelyDead || target.health <= 0);\r\n\tconst hadVenomous = (damageSource as BoardEntity).venomous;\r\n\r\n\tfor (const target of targets) {\r\n\t\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t\t// without it\r\n\t\tconst fakeAttacker = {\r\n\t\t\t...(damageSource || {}),\r\n\t\t\tentityId: -1,\r\n\t\t\tattack: damage,\r\n\t\t\t// attacking: true,\r\n\t\t} as BoardEntity;\r\n\t\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\t\tactualDamagesDone.push(actualDamageDone);\r\n\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// TODO: why isn't it done in bumpEntities?\r\n\t\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t\t// the divine shield once both bumps are done\r\n\t\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\t\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t\t}\r\n\t}\r\n\r\n\tconst spawns = [];\r\n\tfor (let i = 0; i < targets.length; i++) {\r\n\t\tconst target = targets[i];\r\n\t\tconst actualDamageDone = actualDamagesDone[i];\r\n\t\tconst isDeadBeforeDamage = areDeadBeforeDamage[i];\r\n\t\tif (actualDamageDone > 0) {\r\n\t\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\t\ttarget,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tdamageSource,\r\n\t\t\t\tactualDamageDone,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\r\n\t\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\t\tonMinionKill(\r\n\t\t\t\t\tdamageSource as BoardEntity,\r\n\t\t\t\t\thadVenomous,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tboard,\r\n\t\t\t\t\thero,\r\n\t\t\t\t\t[],\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst defendingEntityIndex = board.map((entity) => entity.entityId).indexOf(target.entityId);\r\n\t\tboard[defendingEntityIndex] = target;\r\n\t}\r\n\treturn actualDamagesDone.reduce((a, b) => a + b, 0);\r\n};\r\n\r\nexport const getDefendingEntity = (\r\n\tdefendingBoard: BoardEntity[],\r\n\tattackingEntity: BoardEntity,\r\n\tignoreTaunts = false,\r\n): BoardEntity => {\r\n\tif (debugState.active) {\r\n\t\tfor (const forcedFaceOff of debugState.forcedFaceOff) {\r\n\t\t\tif (debugState.isCorrectEntity(forcedFaceOff.attacker, attackingEntity)) {\r\n\t\t\t\t// if (attackingEntity.entityId === forcedFaceOff.attacker.entityId) {\r\n\t\t\t\tconst def = defendingBoard.find((e) => debugState.isCorrectEntity(forcedFaceOff.defender, e));\r\n\t\t\t\tif (!!def) {\r\n\t\t\t\t\t// Remove the face-off\r\n\t\t\t\t\tdebugState.forcedFaceOff = debugState.forcedFaceOff.filter((f) => f != forcedFaceOff);\r\n\t\t\t\t\treturn def;\r\n\t\t\t\t}\r\n\t\t\t\t// }\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tlet possibleDefenders: readonly BoardEntity[];\r\n\tif (\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_BGS_022 ||\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_TB_BaconUps_091 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845_G\r\n\t) {\r\n\t\tconst minAttack = Math.min(...defendingBoard.map((entity) => entity.attack));\r\n\t\tpossibleDefenders = defendingBoard.filter((entity) => entity.attack === minAttack);\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921 ||\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921_G\r\n\t) {\r\n\t\tpossibleDefenders = defendingBoard\r\n\t\t\t.filter(\r\n\t\t\t\t(entity) =>\r\n\t\t\t\t\tentity.health <= attackingEntity.attack || attackingEntity.venomous || attackingEntity.poisonous,\r\n\t\t\t)\r\n\t\t\t.filter((e) => !e.divineShield);\r\n\t\tif (!possibleDefenders.length) {\r\n\t\t\tpossibleDefenders = defendingBoard;\r\n\t\t}\r\n\t} else {\r\n\t\tpossibleDefenders = defendingBoard.filter((e) => !e.stealth);\r\n\t\tif (!ignoreTaunts) {\r\n\t\t\tconst taunts = possibleDefenders.filter((entity) => entity.taunt);\r\n\t\t\tpossibleDefenders = taunts.length > 0 ? taunts : possibleDefenders;\r\n\t\t}\r\n\t}\r\n\r\n\tconst chosenDefender = pickRandom(possibleDefenders);\r\n\t// if (chosenDefender?.taunt) {\r\n\t// \tconst elistras = defendingBoard.filter(\r\n\t// \t\t(entity) =>\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_BGS_205 ||\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_TB_BaconUps_306,\r\n\t// \t);\r\n\t// \tif (elistras.length > 0) {\r\n\t// \t\tchosenDefender = elistras[Math.floor(Math.random() * elistras.length)];\r\n\t// \t}\r\n\t// }\r\n\treturn chosenDefender;\r\n};\r\n\r\nexport const bumpEntities = (\r\n\tentity: BoardEntity,\r\n\tbumpInto: BoardEntity,\r\n\tentityBoard: BoardEntity[],\r\n\tentityBoardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tapplyVenomous = true,\r\n\tforceVenomous = false,\r\n): number => {\r\n\t// No attack has no impact\r\n\tconst debug = bumpInto.cardId === 'BG26_888';\r\n\tif (bumpInto.attack === 0) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// Matador effect has priority\r\n\tif (\r\n\t\tentity.abiityChargesLeft > 0 &&\r\n\t\t(entity.cardId === CardIds.MadMatador_BG28_404 || entity.cardId === CardIds.MadMatador_BG28_404_G)\r\n\t) {\r\n\t\tentity.abiityChargesLeft--;\r\n\t\tconst newTarget = pickRandom(otherBoard);\r\n\t\tif (newTarget) {\r\n\t\t\tgameState.spectator.registerPowerTarget(entity, newTarget, otherBoard, entityBoardHero, otherHero);\r\n\t\t\t// TODO: here the MadMatador is the source of the damage, not the initial attacker\r\n\t\t\t// Not sure exactly what the impact would be, as there is no counter\r\n\t\t\tconst newSource = {\r\n\t\t\t\t...entity,\r\n\t\t\t\tattack: bumpInto.attack,\r\n\t\t\t\t// attacking: true,\r\n\t\t\t} as BoardEntity;\r\n\t\t\tconst defenderHadDivineShield = newTarget.divineShield;\r\n\t\t\tconst damageDone = bumpEntities(\r\n\t\t\t\tnewTarget,\r\n\t\t\t\tnewSource,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tentityBoard,\r\n\t\t\t\tentityBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\tfalse,\r\n\t\t\t);\r\n\t\t\tif (newSource.attack > 0 && defenderHadDivineShield) {\r\n\t\t\t\tupdateDivineShield(newTarget, otherBoard, otherHero, entityBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (damageDone > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tnewTarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tentityBoard,\r\n\t\t\t\t\tentityBoardHero,\r\n\t\t\t\t\tnewSource,\r\n\t\t\t\t\tdamageDone,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\treturn damageDone;\r\n\t\t}\r\n\t}\r\n\r\n\tif (entity.divineShield) {\r\n\t\tgameState.spectator.registerDamageDealt(bumpInto, entity, 0, entityBoard);\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst damageDealt = (entity.damageMultiplier || 1) * bumpInto.attack;\r\n\tentity.health = entity.health - damageDealt;\r\n\t// FIXME: This will likely be incorrect in terms of timings, e.g. if the entity ends up\r\n\t// surviving following a buff like Spawn.\r\n\tgameState.spectator.registerDamageDealt(bumpInto, entity, damageDealt, entityBoard);\r\n\r\n\t// if (entity.cardId === CardIds.Bubblette_BG_TID_713 && bumpInto.attack === 1) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// } else if (entity.cardId === CardIds.Bubblette_BG_TID_713_G && bumpInto.attack === 2) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// }\r\n\t// Do it last, so that other effects are still processed\r\n\tif (bumpInto.poisonous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t}\r\n\tif ((bumpInto.venomous || forceVenomous) && applyVenomous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t\tupdateVenomous(bumpInto, false, otherBoard, otherHero, entityBoardHero, gameState);\r\n\t}\r\n\t// Ideally we should do the Reckoning stuff here. However, at this point we only have half the damage\r\n\t// information, so it is possible that the entity deals more than 3 (which should trigger Reckoning)\r\n\t// but dies during the exchange (and Reckoning doesn't trigger then)\r\n\r\n\tentity.lastAffectedByEntity = bumpInto;\r\n\t// if (entity.frenzyChargesLeft > 0 && entity.health > 0 && !entity.definitelyDead) {\r\n\t// \tapplyFrenzy(entity, entityBoard, entityBoardHero, gameState);\r\n\t// \tentity.frenzyChargesLeft--;\r\n\t// }\r\n\r\n\t// We spawn them here, because it says \"whenever\", and so happens right away\r\n\t// FIXME: there could be a bug here, if a Cleave attacks several IGB at the same time. The current\r\n\t// implementation could spawn minions above the max board size. Fringe case though, so leaving it\r\n\t// like this for now\r\n\t// const entitySpawns = getWheneverEntitySpawns(\r\n\t// \tentity,\r\n\t// \tentityBoard,\r\n\t// \tentityBoardHero,\r\n\t// \totherBoard,\r\n\t// \totherHero,\r\n\t// \tgameState.allCards,\r\n\t// \tgameState.cardsData,\r\n\t// \tgameState.sharedState,\r\n\t// \tgameState.spectator,\r\n\t// );\r\n\t// if (!!entitySpawns?.length) {\r\n\t// \t// Spawn to the right\r\n\t// \tconst index = entityBoard.map((e) => e.entityId).indexOf(entity.entityId) + 1;\r\n\t// \taddMinionsToBoard(entityBoard, entityBoardHero, otherHero, index, entitySpawns, gameState);\r\n\t// \tgameState.spectator.registerMinionsSpawn(entity, entityBoard, entitySpawns);\r\n\t// }\r\n\treturn bumpInto.attack;\r\n};\r\n\r\n// const getWheneverEntitySpawns = (\r\n// \tentity: BoardEntity,\r\n// \tentityBoard: BoardEntity[],\r\n// \tentityBoardHero: BgsPlayerEntity,\r\n// \totherBoard: BoardEntity[],\r\n// \totherHero: BgsPlayerEntity,\r\n// \tallCards: AllCardsService,\r\n// \tcardsData: CardsData,\r\n// \tsharedState: SharedState,\r\n// \tspectator: Spectator,\r\n// ): readonly BoardEntity[] => {\r\n// \tif (entityBoard.length === 7) {\r\n// \t\treturn null;\r\n// \t}\r\n\r\n// \tif (entity.cardId === CardIds.ImpGangBoss_BRM_006) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_BRM_006t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpGangBoss_TB_BaconUps_030) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_TB_BaconUps_030t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpMama_BGS_044) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.ImpMama_TB_BaconUps_116) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t2,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_BOT_218) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_BOT_218t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_TB_BaconUps_041) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_TB_BaconUps_041t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t}\r\n// \treturn null;\r\n// };\r\n\r\nexport const processMinionDeath = (\r\n\tboard1: BoardEntity[],\r\n\tboard1Hero: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tboard2Hero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\t// When we're in an \"attack immediately\" phase, we wait until we're out of the phase to summon minions\r\n\tskipSummonWhenSpace = false,\r\n): void => {\r\n\t// const debug = board1.some((e) => e.health <= 0) || board2.some((e) => e.health <= 0);\r\n\t// debug && console.debug('\\nprocessing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\tconst [deadMinionIndexesFromLeft1, deadMinionIndexesFromRights1, deadEntities1] = makeMinionsDie(\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\tconst [deadMinionIndexesFromLeft2, deadMinionIndexesFromRights2, deadEntities2] = makeMinionsDie(\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tgameState,\r\n\t);\r\n\t// debug && console.debug('after processing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\t// debug && console.debug(deadMinionIndexesFromRights1);\r\n\t// debug && console.debug(deadMinionIndexesFromRights2);\r\n\t// console.debug('dead entities', stringifySimple(deadEntities1, allCards), stringifySimple(deadEntities2, allCards));\r\n\t// No death to process, we can return\r\n\tif (deadEntities1.length === 0 && deadEntities2.length === 0) {\r\n\t\treturn;\r\n\t\t// return [board1, board2];\r\n\t}\r\n\r\n\t// Remember them right away, so that subsequent deaths do not break the order\r\n\t// TODO: move this to the deathrattle-orchestration?\r\n\t// If the fish dies (from Scallywag for instance), it doesn't remember the deathrattle\r\n\t// console.debug(\r\n\t// \t'\\n\\ndeadEntities',\r\n\t// \tstringifySimple(deadEntities1, gameState.allCards),\r\n\t// \tstringifySimple(deadEntities2, gameState.allCards),\r\n\t// );\r\n\r\n\tgameState.spectator.registerDeadEntities(\r\n\t\tdeadMinionIndexesFromRights1,\r\n\t\tdeadEntities1,\r\n\t\tboard1,\r\n\t\tdeadMinionIndexesFromRights2,\r\n\t\tdeadEntities2,\r\n\t\tboard2,\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities1.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft1[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities2.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft2[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\r\n\tfor (const deadEntity of deadEntities1) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board1Hero,\r\n\t\t\t\tboard: board1,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const deadEntity of deadEntities2) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board2Hero,\r\n\t\t\t\tboard: board2,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tboard1Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard1Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities1.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\tboard2Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard2Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities2.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\r\n\torchestrateMinionDeathEffects({\r\n\t\tgameState: gameState,\r\n\t\tplayerDeadEntities: board1Hero.friendly ? deadEntities1 : deadEntities2,\r\n\t\tplayerDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights1\r\n\t\t\t: deadMinionIndexesFromRights2,\r\n\t\topponentDeadEntities: board1Hero.friendly ? deadEntities2 : deadEntities1,\r\n\t\topponentDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights2\r\n\t\t\t: deadMinionIndexesFromRights1,\r\n\t});\r\n\r\n\t// Make sure we only return when there are no more deaths to process\r\n\t// Make sure to do this right before the end of the process\r\n\t// FIXME: this will propagate the killer between rounds, which is incorrect. For instance,\r\n\t// if a dragon kills a Ghoul, then the Ghoul's deathrattle kills a Kaboom, the killer should\r\n\t// now be the ghoul. Then if the Kaboom kills someone, the killer should again change. You could\r\n\t// also have multiple killers, which is not taken into account here.\r\n\t// The current assumption is that it's a suffienctly fringe case to not matter too much\r\n\tprocessMinionDeath(board1, board1Hero, board2, board2Hero, gameState);\r\n\r\n\t// Not sure about the timing here, but I have bothered Mitchell quite a lot already recently :)\r\n\tif (!skipSummonWhenSpace) {\r\n\t\thandleSummonsWhenSpace(board1, board1Hero, board2, board2Hero, gameState);\r\n\t}\r\n\r\n\t// Apply \"after minion death\" effects\r\n\thandleAfterMinionsDeaths(\r\n\t\tboard1,\r\n\t\tdeadEntities1,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights1 : deadMinionIndexesFromRights2,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tdeadEntities2,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights2 : deadMinionIndexesFromRights1,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\r\n\t// Only when all deathrattles have resolved\r\n\t// 2025-12-20: https://replays.firestoneapp.com/?reviewId=7d8f9af4-b484-4256-976b-ff9df8847b50&turn=5&action=0\r\n\t// Confirmed by dev that the fish doesn't get the deathrattle in this case\r\n\tboard1\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities1, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\tboard2\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities2, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\r\n\tresolvePendingEffects(board1, board1Hero, board2, board2Hero, gameState);\r\n};\r\n\r\nconst handleAfterMinionsDeaths = (\r\n\tboard1: BoardEntity[],\r\n\tdeadEntities1: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight1: number[],\r\n\theroEntity1: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tdeadEntities2: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight2: number[],\r\n\theroEntity2: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst random = Math.random() > 0.5;\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\trandom ? board1 : board2,\r\n\t\trandom ? deadEntities1 : deadEntities2,\r\n\t\trandom ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\trandom ? heroEntity1 : heroEntity2,\r\n\t\trandom ? board2 : board1,\r\n\t\trandom ? deadEntities2 : deadEntities1,\r\n\t\trandom ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\trandom ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\t!random ? board1 : board2,\r\n\t\t!random ? deadEntities1 : deadEntities2,\r\n\t\t!random ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\t!random ? heroEntity1 : heroEntity2,\r\n\t\t!random ? board2 : board1,\r\n\t\t!random ? deadEntities2 : deadEntities1,\r\n\t\t!random ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\t!random ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nconst handleAfterMinionsDeathsForBoard = (\r\n\tfriendlyBoard: BoardEntity[],\r\n\tfriendlyDeadEntities: BoardEntity[],\r\n\tfriendlyDeadEntitiesIndexesFromRight: number[],\r\n\tfriendlyHeroEntity: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherDeadEntities: BoardEntity[],\r\n\totherDeadEntitiesIndexesFromRight: number[],\r\n\totherHeroEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities = [];\r\n\r\n\tfor (const trinket of friendlyHeroEntity.trinkets ?? []) {\r\n\t\tconst onAfterDeathImpl = cardMappings[trinket.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(trinket, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const entity of friendlyBoard) {\r\n\t\tconst onAfterDeathImpl = cardMappings[entity.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(entity, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tconst secretTriggered = null;\r\n\t// if (\r\n\t// \t(secretTriggered = friendlyHeroEntity.secrets?.find(\r\n\t// \t\t(secret) => !secret.triggered && secret?.cardId === CardIds.MagicBlackSoulstone,\r\n\t// \t)) != null\r\n\t// ) {\r\n\t// \tif (friendlyBoard.length === 0) {\r\n\t// \t\tsecretTriggered.triggered = true;\r\n\t// \t\tfor (let i = 0; i < 2; i++) {\r\n\t// \t\t\tconst toSummon = pickRandom(gameState.cardsData.demonSpawns);\r\n\t// \t\t\tcandidateEntities.push(\r\n\t// \t\t\t\t...spawnEntities(\r\n\t// \t\t\t\t\ttoSummon,\r\n\t// \t\t\t\t\t1,\r\n\t// \t\t\t\t\tfriendlyBoard,\r\n\t// \t\t\t\t\tfriendlyHeroEntity,\r\n\t// \t\t\t\t\totherBoard,\r\n\t// \t\t\t\t\totherHeroEntity,\r\n\t// \t\t\t\t\tgameState,\r\n\t// \t\t\t\t\tfriendlyHeroEntity.friendly,\r\n\t// \t\t\t\t\tfalse,\r\n\t// \t\t\t\t),\r\n\t// \t\t\t);\r\n\t// \t\t}\r\n\t// \t}\r\n\t// }\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tfriendlyBoard,\r\n\t\tfriendlyHeroEntity,\r\n\t\tsecretTriggered,\r\n\t\t0,\r\n\t\totherBoard,\r\n\t\totherHeroEntity,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport interface OnDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnAfterDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly deadEntities: BoardEntity[];\r\n\treadonly deadEntitiesIndexesFromRight: number[];\r\n\treadonly gameState: FullGameState;\r\n}\r\n\r\n/** A friendly board minion just died (during death processing). Implementations filter (e.g. Taunt) as needed. */\r\nexport interface OnAfterFriendlyMinionDeathInput {\r\n\treadonly deadEntity: BoardEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly boardBeforeProcs: BoardEntity[];\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnMinionKilledInput {\r\n\treadonly killer: BoardEntity;\r\n\treadonly hadVenomous: boolean;\r\n\treadonly killerIsAttacking: boolean;\r\n\treadonly minionKilled: BoardEntity;\r\n\treadonly attackingHero: BgsPlayerEntity;\r\n\treadonly attackingBoard: BoardEntity[];\r\n\treadonly defendingHero: BgsPlayerEntity;\r\n\treadonly defendingBoard: BoardEntity[];\r\n\treadonly defenderNeighbours: readonly BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n\treadonly playerIsFriendly: boolean;\r\n}\r\n"]}
1
+ {"version":3,"file":"attack.js","sourceRoot":"","sources":["../../src/simulation/attack.ts"],"names":[],"mappings":";;;AAIA,4DAAsE;AACtE,iEAA4D;AAC5D,gDAA4C;AAC5C,6DAA+D;AAC/D,mDAAsD;AAEtD,6CAAgE;AAChE,oCAAsE;AACtE,iDAAmF;AACnF,qDAAmD;AACnD,+DAA6D;AAC7D,2EAA4E;AAC5E,6DAAqD;AAErD,iDAAgD;AAChD,+CAA6C;AAC7C,2CAAmD;AACnD,2DAAgE;AAChE,uDAA0D;AAC1D,qCAA+C;AAC/C,mCAAgD;AAChD,2DAA6D;AAC7D,uDAAiD;AAG1C,MAAM,cAAc,GAAG,CAC7B,cAA6B,EAC7B,kBAAmC,EACnC,cAA6B,EAC7B,kBAAmC,EACnC,SAAwB,EACxB,OAGC,EACa,EAAE;;IAOhB,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;QAC/D,OAAO;KACP;IAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,cAAc,EAAE,kBAAkB,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnG,IAAI,eAAe,EAAE;QACpB,SAAS,CAAC,WAAW,CAAC,uBAAuB,GAAG,eAAe,CAAC,QAAQ,CAAC;QAGzE,MAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACrE,MAAM,0BAA0B,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;QACjF,MAAM,sBAAsB,GAAG,eAAe,CAAC,iBAAiB,CAAC;QAUjE,IAAI,CAAC,sBAAsB,EAAE;YAG5B,0BAA0B,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;YACzE,kBAAkB,CAAC,gBAAgB,GAAG,CAAC,CAAC;SACxC;aAAM;YAEN,eAAe,CAAC,iBAAiB,GAAG,KAAK,CAAC;SAC1C;QAED,MAAM,eAAe,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE;YAEzC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;gBAG/D,MAAM;aACN;YAED,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,eAAe,CAAC,QAAQ,CAAC,EAAE;gBAClF,MAAM,eAAe,GACpB,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,WAAW,mCAAI,IAAA,0BAAkB,EAAC,cAAc,EAAE,eAAe,CAAC,CAAC;gBAE7E,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE;oBACrF,IAAA,oBAAY,EACX,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,OAAO,CACP,CAAC;iBACF;qBAAM;oBAEN,eAAe,CAAC,iBAAiB,GAAG,KAAK,CAAC;iBAC1C;aACD;SACD;QACD,SAAS,CAAC,WAAW,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACrD,eAAe,CAAC,WAAW,GAAG,CAAC,CAAC;QAChC,kBAAkB,CAAC,gBAAgB,GAAG,CAAC,CAAC;KACxC;IACD,OAAO,eAAe,CAAC;AACxB,CAAC,CAAC;AAnFW,QAAA,cAAc,kBAmFzB;AAEK,MAAM,YAAY,GAAG,CAC3B,eAA4B,EAC5B,cAA6B,EAC7B,kBAAmC,EACnC,eAA4B,EAC5B,cAA6B,EAC7B,kBAAmC,EACnC,SAAwB,EACxB,OAEC,EACA,EAAE;;IACH,MAAM,sBAAsB,GAAG,eAAe,CAAC,iBAAiB,CAAC;IACjE,SAAS,CAAC,SAAS,CAAC,cAAc,CACjC,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,kBAAkB,CAClB,CAAC;IAGF,IAAA,6CAAyB,EACxB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;IACF,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GACjG,IAAA,gCAAoB,EACnB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;IACH,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,GAAG,aAAa,CACjH,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;IACF,MAAM,oBAAoB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;IAC3E,MAAM,oBAAoB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;IAiB3E,IAAA,sCAAuB,EACtB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,SAAS,CACT,CAAC;IAEF,IAAA,0BAAkB,EACjB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,mBAAmB,KAAI,sBAAsB,CACtD,CAAC;IAEF,IAAA,uCAAwB,EACvB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,SAAS,CACT,CAAC;IACF,IAAA,6BAAqB,EAAC,SAAS,CAAC,CAAC;IACjC,eAAe,CAAC,uBAAuB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAA,eAAe,CAAC,uBAAuB,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAY3G,CAAC,CAAC;AAlHW,QAAA,YAAY,gBAkHvB;AAEF,MAAM,aAAa,GAAG,CACrB,eAA4B,EAC5B,eAA4B,EAC5B,cAA6B,EAC7B,kBAAmC,EACnC,cAA6B,EAC7B,kBAAmC,EACnC,SAAwB,EACyC,EAAE;IACnE,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC;IAE7C,IAAI,0BAA0D,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAiB,CAAC,EAAE;QAC3G,MAAM,MAAM,GAAG,IAAA,kCAAa,EAC3B,eAAe,CAAC,MAAM,iBAAiC;YACtD,CAAC;YACD,CAAC,aAAiC,EACnC,CAAC,EACD,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,IAAI,CACJ,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAC5D,MAAM,YAAY,GAAG,IAAA,4BAAmB,EACvC,MAAM,EACN,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;YACF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE;gBACvC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE;oBAClE,aAAa,CACZ,WAAW,EACX,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;iBACF;aACD;SACD;KACD;IAGD,MAAM,yBAAyB,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC;IAEhG,MAAM,uBAAuB,GAAG,eAAe,CAAC,YAAY,CAAC;IAC7D,MAAM,uBAAuB,GAAG,eAAe,CAAC,YAAY,CAAC;IAG7D,MAAM,kBAAkB,GAA2B,IAAA,qBAAa,EAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IAClG,IAAI,yBAAyB,EAAE;QAC9B,IAAI,CAAC,eAAe,CAAC,uBAAuB,EAAE;YAE7C,oBAAoB,IAAI,IAAA,oBAAY,EACnC,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;SACF;QACD,oBAAoB,IAAI,IAAA,oBAAY,EACnC,eAAe,EACf,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,CACT,CAAC;QACF,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAuB,IAAI,CAAC,eAAe,CAAC,uBAAuB,EAAE;YACtG,IAAA,kCAAkB,EACjB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,EACL,SAAS,CACT,CAAC;SACF;QACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAuB,EAAE;YAC1D,IAAA,kCAAkB,EACjB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,EACL,SAAS,CACT,CAAC;SACF;QAID,IAAI,oBAAoB,GAAG,CAAC,EAAE;YAC7B,IAAA,gCAAe,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,SAAS,CACT,CAAC;SACF;QACD,IAAI,oBAAoB,GAAG,CAAC,EAAE;YAC7B,IAAA,gCAAe,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,SAAS,CACT,CAAC;SACF;QAED,IAAI,eAAe,CAAC,MAAM,IAAI,CAAC,IAAI,eAAe,CAAC,cAAc,EAAE;YAClE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,IAAA,0BAAY,EAC5D,eAAe,EACf,WAAW,EACX,IAAI,EACJ,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,CACT,CAAC;YACF,oBAAoB,IAAI,iBAAiB,CAAC;YAC1C,oBAAoB,IAAI,iBAAiB,CAAC;SAC1C;QACD,IAAI,eAAe,CAAC,MAAM,IAAI,CAAC,IAAI,eAAe,CAAC,cAAc,EAAE;YAClE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,IAAA,0BAAY,EAC5D,eAAe,EACf,KAAK,EACL,KAAK,EACL,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,CACT,CAAC;YACF,oBAAoB,IAAI,iBAAiB,CAAC;YAC1C,oBAAoB,IAAI,iBAAiB,CAAC;SAC1C;KACD;IAED,IAAI,eAAe,CAAC,MAAM,EAAE;QAC3B,KAAK,MAAM,SAAS,IAAI,kBAAkB,EAAE;YAC3C,MAAM,gBAAgB,GAAG,IAAA,oBAAY,EACpC,SAAS,EACT,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,WAAW,CACX,CAAC;YACF,oBAAoB,IAAI,gBAAgB,CAAC;YAGzC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,YAAY,EAAE;gBACzD,IAAA,kCAAkB,EAAC,SAAS,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;aACxG;YACD,IAAI,gBAAgB,GAAG,CAAC,EAAE;gBACzB,IAAA,gCAAe,EACd,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,SAAS,CACT,CAAC;aACF;YACD,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,SAAS,CAAC,cAAc,EAAE;gBACtD,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,IAAA,0BAAY,EAC5D,eAAe,EACf,WAAW,EACX,IAAI,EACJ,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,CACT,CAAC;gBACF,oBAAoB,IAAI,iBAAiB,CAAC;gBAC1C,oBAAoB,IAAI,iBAAiB,CAAC;aAC1C;SACD;KACD;IAED,eAAe,CAAC,iBAAiB,GAAG,KAAK,CAAC;IAC1C,IAAI,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,uBAA8C,CAAC,EAAE;QACrG,eAAe,CAAC,cAAc,GAAG,IAAI,CAAC;KACtC;IACD,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC;AACvD,CAAC,CAAC;AAIF,MAAM,kBAAkB,GAAG,CAC1B,cAA6B,EAC7B,kBAAmC,EACnC,QAAyB,EACX,EAAE;IAChB,IAAI,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,wBAAS,EAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE;QAChC,OAAO,IAAI,CAAC;KACZ;IAED,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;QAC9D,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;KAC7E;SAAM,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,EAAE;QAC9D,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC;QAC3D,kBAAkB,CAAC,gBAAgB,GAAG,SAAS,CAAC;KAChD;SAAM;QACN,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,IAAI,SAAS,CAAC,CAAC;KACpF;IACD,MAAM,QAAQ,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC;AAEK,MAAM,kBAAkB,GAAG,CACjC,cAA6B,EAC7B,MAAmB,EACnB,oBAA4B,EAC5B,cAA6B,EAC7B,eAAuB,EACvB,QAAyB,EACT,EAAE;IAClB,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;QAE9B,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,GAAG,oBAAoB,GAAG,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAGxF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE;YACzC,MAAM,eAAe,GAAG,cAAc;iBACpC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;iBAChD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAErC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE;gBAC5B,MAAM;aACN;YAED,MAAM,YAAY,GAAG,IAAA,uBAAe,EAAC,CAAC,CAAc,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAC1G,eAAe,CACf,CAAC;YACF,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;iBACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;iBACd,IAAI,EAAE,CAAC;YACT,MAAM,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,eAAe,IAAI,IAAI,EAAE;gBAM5B,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC;gBACzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACpB;SAED;KACD;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC,CAAC;AA5CW,QAAA,kBAAkB,sBA4C7B;AAEK,MAAM,aAAa,GAAG,CAC5B,KAAoB,EACpB,MAAmB,EACnB,wBAAiC,EACjC,iBAAiB,GAAG,KAAK,EACA,EAAE;IAC3B,MAAM,UAAU,GAAG,EAAE,CAAC;IAEtB,IAAI,wBAAwB,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChE,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,wBAAwB,CAAC;QACvE,MAAM,aAAa,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAChD,IAAI,aAAa,EAAE;YAClB,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;SAC/B;QAGD,MAAM,mBAAmB,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,wBAAwB,GAAG,CAAC,CAAC,CAAC;QAC9E,MAAM,cAAc,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAClD,IAAI,cAAc,EAAE;YACnB,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;SAChC;KACD;SAAM;QACN,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrE,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE;YACnB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;SAClC;aAAM,IAAI,iBAAiB,EAAE;YAC7B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACtB;QAED,IAAI,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE;YAC7B,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;SAClC;aAAM,IAAI,iBAAiB,EAAE;YAC7B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACtB;KACD;IACD,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AApCW,QAAA,aAAa,iBAoCxB;AAEK,MAAM,gBAAgB,GAAG,CAC/B,KAAoB,EACpB,MAAmB,EACnB,wBAAiC,EACnB,EAAE;IAEhB,IAAI,wBAAwB,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChE,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,wBAAwB,CAAC;QACvE,MAAM,aAAa,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAChD,IAAI,aAAa,EAAE;YAClB,OAAO,aAAa,CAAC;SACrB;KACD;SAAM;QACN,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrE,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE;YACnB,OAAO,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;SACxB;KACD;IACD,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAnBW,QAAA,gBAAgB,oBAmB3B;AAEK,MAAM,uBAAuB,GAAG,CACtC,gBAA+B,EAC/B,oBAAqC,EACrC,YAAyB,EACzB,MAAc,EACd,qBAAoC,EACpC,yBAA0C,EAC1C,SAAwB,EACjB,EAAE;IACT,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;QAClC,OAAO;KACP;IACD,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACvF,MAAM,eAAe,GAAgB,IAAA,kBAAU,EAAC,YAAY,CAAC,CAAC;IAC9D,IAAI,eAAe,EAAE;QACpB,SAAS,CAAC,SAAS,CAAC,mBAAmB,CACtC,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,CACzB,CAAC;QACF,IAAA,0BAAkB,EACjB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EACZ,MAAM,EACN,qBAAqB,EACrB,yBAAyB,EACzB,SAAS,CACT,CAAC;KACF;AACF,CAAC,CAAC;AAjCW,QAAA,uBAAuB,2BAiClC;AAEK,MAAM,kBAAkB,GAAG,CACjC,MAAmB,EACnB,KAAoB,EACpB,IAAqB,EACrB,YAA2C,EAC3C,MAAc,EACd,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACf,EAAE;IAEX,IAAI,CAAC,MAAM,EAAE;QACZ,OAAO,CAAC,CAAC;KACT;IAED,MAAM,kBAAkB,GAAG,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACvE,MAAM,WAAW,GAAI,YAA4B,CAAC,QAAQ,CAAC;IAC3D,MAAM,MAAM,GAAG,EAAE,CAAC;IAIlB,MAAM,YAAY,GAAG;QACpB,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QACvB,QAAQ,EAAE,CAAC,CAAC;QACZ,MAAM,EAAE,MAAM;KAEC,CAAC;IACjB,MAAM,gBAAgB,GAAG,IAAA,oBAAY,EAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAQ3G,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE;QACnD,IAAA,kCAAkB,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;KACrE;IAED,IAAI,gBAAgB,GAAG,CAAC,EAAE;QAEzB,MAAM,SAAS,GAAG,IAAA,gCAAe,EAChC,MAAM,EACN,KAAK,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,SAAS,CACT,CAAC;KACF;IACD,IAAI,CAAC,kBAAkB,IAAI,gBAAgB,GAAG,CAAC,IAAI,QAAQ,IAAI,YAAY,IAAI,QAAQ,IAAI,YAAY,EAAE;QACxG,MAAM,CAAC,oBAAoB,GAAG,YAA2B,CAAC;QAC1D,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE;YAChD,IAAA,0BAAY,EACX,YAA2B,EAC3B,WAAW,EACX,KAAK,EACL,MAAM,EACN,UAAU,EACV,SAAS,EACT,KAAK,EACL,IAAI,EACJ,EAAE,EACF,SAAS,CACT,CAAC;SACF;KACD;IACD,IAAI,gBAAgB,GAAG,CAAC,EAAE;QACzB,IAAI,IAAA,qBAAa,EAAC,YAAY,CAAC,EAAE;YAChC,YAAY,CAAC,QAAQ,GAAG,KAAK,CAAC;SAC9B;KACD;IACD,MAAM,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9F,KAAK,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;IACrC,OAAO,gBAAgB,CAAC;AACzB,CAAC,CAAC;AA7EW,QAAA,kBAAkB,sBA6E7B;AAGK,MAAM,mBAAmB,GAAG,CAClC,OAAsB,EACtB,KAAoB,EACpB,IAAqB,EACrB,YAA2C,EAC3C,MAAc,EACd,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACf,EAAE;IAEX,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAA,EAAE;QACrB,OAAO,CAAC,CAAC;KACT;IAED,MAAM,iBAAiB,GAAG,EAAE,CAAC;IAC7B,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IACjG,MAAM,WAAW,GAAI,YAA4B,CAAC,QAAQ,CAAC;IAE3D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAI7B,MAAM,YAAY,GAAG;YACpB,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;YACvB,QAAQ,EAAE,CAAC,CAAC;YACZ,MAAM,EAAE,MAAM;SAEC,CAAC;QACjB,MAAM,gBAAgB,GAAG,IAAA,oBAAY,EAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3G,iBAAiB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAQzC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,EAAE;YACnD,IAAA,kCAAkB,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;SACrE;KACD;IAED,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,gBAAgB,GAAG,CAAC,EAAE;YAEzB,MAAM,SAAS,GAAG,IAAA,gCAAe,EAChC,MAAM,EACN,KAAK,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,SAAS,CACT,CAAC;SACF;QACD,IAAI,CAAC,kBAAkB,IAAI,gBAAgB,GAAG,CAAC,IAAI,QAAQ,IAAI,YAAY,IAAI,QAAQ,IAAI,YAAY,EAAE;YACxG,MAAM,CAAC,oBAAoB,GAAG,YAA2B,CAAC;YAE1D,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,cAAc,EAAE;gBAChD,IAAA,0BAAY,EACX,YAA2B,EAC3B,WAAW,EACX,KAAK,EACL,MAAM,EACN,UAAU,EACV,SAAS,EACT,KAAK,EACL,IAAI,EACJ,EAAE,EACF,SAAS,CACT,CAAC;aACF;SACD;QACD,MAAM,oBAAoB,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC7F,KAAK,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAAC;KACrC;IACD,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;AACrD,CAAC,CAAC;AAnFW,QAAA,mBAAmB,uBAmF9B;AAEK,MAAM,kBAAkB,GAAG,CACjC,cAA6B,EAC7B,eAA4B,EAC5B,YAAY,GAAG,KAAK,EACN,EAAE;IAChB,IAAI,wBAAU,CAAC,MAAM,EAAE;QACtB,KAAK,MAAM,aAAa,IAAI,wBAAU,CAAC,aAAa,EAAE;YACrD,IAAI,wBAAU,CAAC,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE;gBAExE,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAU,CAAC,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC9F,IAAI,CAAC,CAAC,GAAG,EAAE;oBAEV,wBAAU,CAAC,aAAa,GAAG,wBAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC;oBACtF,OAAO,GAAG,CAAC;iBACX;aAED;SACD;KACD;IAED,IAAI,iBAAyC,CAAC;IAC9C,IACC,eAAe,CAAC,MAAM,cAAgC;QACtD,eAAe,CAAC,MAAM,sBAAwC;QAC9D,eAAe,CAAC,MAAM,eAAsC;QAC5D,eAAe,CAAC,MAAM,iBAAwC,EAC7D;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7E,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;KACnF;SAAM,IACN,eAAe,CAAC,MAAM,eAAqC;QAC3D,eAAe,CAAC,MAAM,iBAAuC,EAC5D;QACD,iBAAiB,GAAG,cAAc;aAChC,MAAM,CACN,CAAC,MAAM,EAAE,EAAE,CACV,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC,MAAM,IAAI,eAAe,CAAC,QAAQ,IAAI,eAAe,CAAC,SAAS,CACjG;aACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACjC,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE;YAC9B,iBAAiB,GAAG,cAAc,CAAC;SACnC;KACD;SAAM;QACN,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,YAAY,EAAE;YAClB,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClE,iBAAiB,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC;SACnE;KACD;IAED,MAAM,cAAc,GAAG,IAAA,kBAAU,EAAC,iBAAiB,CAAC,CAAC;IAWrD,OAAO,cAAc,CAAC;AACvB,CAAC,CAAC;AA9DW,QAAA,kBAAkB,sBA8D7B;AAEK,MAAM,YAAY,GAAG,CAC3B,MAAmB,EACnB,QAAqB,EACrB,WAA0B,EAC1B,eAAgC,EAChC,UAAyB,EACzB,SAA0B,EAC1B,SAAwB,EACxB,aAAa,GAAG,IAAI,EACpB,aAAa,GAAG,KAAK,EACZ,EAAE;IAEX,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,KAAK,UAAU,CAAC;IAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;QAC1B,OAAO,CAAC,CAAC;KACT;IAGD,IACC,MAAM,CAAC,iBAAiB,GAAG,CAAC;QAC5B,CAAC,MAAM,CAAC,MAAM,eAAgC,IAAI,MAAM,CAAC,MAAM,iBAAkC,CAAC,EACjG;QACD,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;QACzC,IAAI,SAAS,EAAE;YACd,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;YAGnG,MAAM,SAAS,GAAG;gBACjB,GAAG,MAAM;gBACT,MAAM,EAAE,QAAQ,CAAC,MAAM;aAER,CAAC;YACjB,MAAM,uBAAuB,GAAG,SAAS,CAAC,YAAY,CAAC;YACvD,MAAM,UAAU,GAAG,IAAA,oBAAY,EAC9B,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,KAAK,CACL,CAAC;YACF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAuB,EAAE;gBACpD,IAAA,kCAAkB,EAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;aACxF;YACD,IAAI,UAAU,GAAG,CAAC,EAAE;gBACnB,IAAA,gCAAe,EACd,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,UAAU,EACV,SAAS,CACT,CAAC;aACF;YACD,OAAO,UAAU,CAAC;SAClB;KACD;IAED,IAAI,MAAM,CAAC,YAAY,EAAE;QACxB,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAC1E,OAAO,CAAC,CAAC;KACT;IAED,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;IACrE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC;IAG5C,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAQpF,IAAI,QAAQ,CAAC,SAAS,EAAE;QAGvB,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;KAC7B;IACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,aAAa,CAAC,IAAI,aAAa,EAAE;QAG1D,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,IAAA,yBAAc,EAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;KACnF;IAKD,MAAM,CAAC,oBAAoB,GAAG,QAAQ,CAAC;IA2BvC,OAAO,QAAQ,CAAC,MAAM,CAAC;AACxB,CAAC,CAAC;AA3HW,QAAA,YAAY,gBA2HvB;AA+GK,MAAM,kBAAkB,GAAG,CACjC,MAAqB,EACrB,UAA2B,EAC3B,MAAqB,EACrB,UAA2B,EAC3B,SAAwB,EAExB,mBAAmB,GAAG,KAAK,EACpB,EAAE;IAKT,MAAM,CAAC,0BAA0B,EAAE,4BAA4B,EAAE,aAAa,CAAC,GAAG,IAAA,6BAAc,EAC/F,MAAM,EACN,UAAU,EACV,MAAM,EACN,UAAU,EACV,SAAS,CACT,CAAC;IACF,MAAM,CAAC,0BAA0B,EAAE,4BAA4B,EAAE,aAAa,CAAC,GAAG,IAAA,6BAAc,EAC/F,MAAM,EACN,UAAU,EACV,MAAM,EACN,UAAU,EACV,SAAS,CACT,CAAC;IAQF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE;QAC7D,OAAO;KAEP;IAWD,SAAS,CAAC,SAAS,CAAC,oBAAoB,CACvC,4BAA4B,EAC5B,aAAa,EACb,MAAM,EACN,4BAA4B,EAC5B,aAAa,EACb,MAAM,CACN,CAAC;IACF,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAChC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CACjC,IAAA,2BAAmB,EAClB;QACC,GAAG,CAAC;QACJ,MAAM,EAAE,CAAC,CAAC,SAAS;QACnB,cAAc,EAAE,KAAK;QACrB,0BAA0B,EAAE,0BAA0B,CAAC,KAAK,CAAC;KAC7D,EACD,SAAS,CAAC,SAAS,CACnB,CACD,CACD,CAAC;IACF,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAChC,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CACjC,IAAA,2BAAmB,EAClB;QACC,GAAG,CAAC;QACJ,MAAM,EAAE,CAAC,CAAC,SAAS;QACnB,cAAc,EAAE,KAAK;QACrB,0BAA0B,EAAE,0BAA0B,CAAC,KAAK,CAAC;KAC7D,EACD,SAAS,CAAC,SAAS,CACnB,CACD,CACD,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE;QACvC,MAAM,WAAW,GAAG,6BAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,IAAA,2BAAU,EAAC,WAAW,CAAC,EAAE;YAC5B,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE;gBAC/B,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IACD,KAAK,MAAM,UAAU,IAAI,aAAa,EAAE;QACvC,MAAM,WAAW,GAAG,6BAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,IAAA,2BAAU,EAAC,WAAW,CAAC,EAAE;YAC5B,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE;gBAC/B,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,MAAM;gBACb,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IAED,UAAU,CAAC,UAAU,CAAC,0BAA0B;QAC/C,UAAU,CAAC,UAAU,CAAC,0BAA0B;YAChD,aAAa,CAAC,MAAM,CACnB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAmC,IAAI,CAAC,CAAC,MAAM,iBAAqC,CACnG,CAAC,MAAM,CAAC;IACV,UAAU,CAAC,UAAU,CAAC,0BAA0B;QAC/C,UAAU,CAAC,UAAU,CAAC,0BAA0B;YAChD,aAAa,CAAC,MAAM,CACnB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAmC,IAAI,CAAC,CAAC,MAAM,iBAAqC,CACnG,CAAC,MAAM,CAAC;IAEV,IAAA,yDAA6B,EAAC;QAC7B,SAAS,EAAE,SAAS;QACpB,kBAAkB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa;QACvE,gCAAgC,EAAE,UAAU,CAAC,QAAQ;YACpD,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,4BAA4B;QAC/B,oBAAoB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa;QACzE,kCAAkC,EAAE,UAAU,CAAC,QAAQ;YACtD,CAAC,CAAC,4BAA4B;YAC9B,CAAC,CAAC,4BAA4B;KAC/B,CAAC,CAAC;IASH,IAAA,0BAAkB,EAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAGtE,IAAI,CAAC,mBAAmB,EAAE;QACzB,IAAA,0CAAsB,EAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;KAC1E;IAGD,wBAAwB,CACvB,MAAM,EACN,aAAa,EACb,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,4BAA4B,EACjF,UAAU,EACV,MAAM,EACN,aAAa,EACb,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,4BAA4B,EACjF,UAAU,EACV,SAAS,CACT,CAAC;IAKF,MAAM;SACJ,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,cAAM,EAAC,MAAM,CAAC,CAAC;SAClC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACnB,IAAA,0CAAoB,EAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,CAAC,CAC3G,CAAC;IACH,MAAM;SACJ,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,cAAM,EAAC,MAAM,CAAC,CAAC;SAClC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CACnB,IAAA,0CAAoB,EAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,WAAW,CAAC,CAC3G,CAAC;IAEH,IAAA,uCAAqB,EAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AAC1E,CAAC,CAAC;AAzKW,QAAA,kBAAkB,sBAyK7B;AAEF,MAAM,wBAAwB,GAAG,CAChC,MAAqB,EACrB,aAA4B,EAC5B,6BAAuC,EACvC,WAA4B,EAC5B,MAAqB,EACrB,aAA4B,EAC5B,6BAAuC,EACvC,WAA4B,EAC5B,SAAwB,EACvB,EAAE;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC;IACnC,gCAAgC,CAC/B,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACxB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACtC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACtE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAClC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACxB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACtC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACtE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EAClC,SAAS,CACT,CAAC;IACF,gCAAgC,CAC/B,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACzB,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACvC,CAAC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACvE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EACnC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EACzB,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,EACvC,CAAC,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,6BAA6B,EACvE,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,EACnC,SAAS,CACT,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,gCAAgC,GAAG,CACxC,aAA4B,EAC5B,oBAAmC,EACnC,oCAA8C,EAC9C,kBAAmC,EACnC,UAAyB,EACzB,iBAAgC,EAChC,iCAA2C,EAC3C,eAAgC,EAChC,SAAwB,EACvB,EAAE;;IACH,MAAM,iBAAiB,GAAG,EAAE,CAAC;IAE7B,KAAK,MAAM,OAAO,IAAI,MAAA,kBAAkB,CAAC,QAAQ,mCAAI,EAAE,EAAE;QACxD,MAAM,gBAAgB,GAAG,6BAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,IAAA,gCAAe,EAAC,gBAAgB,CAAC,EAAE;YACtC,gBAAgB,CAAC,YAAY,CAAC,OAAO,EAAE;gBACtC,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,aAAa;gBACpB,SAAS,EAAE,eAAe;gBAC1B,UAAU,EAAE,UAAU;gBACtB,YAAY,EAAE,oBAAoB;gBAClC,4BAA4B,EAAE,oCAAoC;gBAClE,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IACD,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE;QACnC,MAAM,gBAAgB,GAAG,6BAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,IAAA,gCAAe,EAAC,gBAAgB,CAAC,EAAE;YACtC,gBAAgB,CAAC,YAAY,CAAC,MAAM,EAAE;gBACrC,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,aAAa;gBACpB,SAAS,EAAE,eAAe;gBAC1B,UAAU,EAAE,UAAU;gBACtB,YAAY,EAAE,oBAAoB;gBAClC,4BAA4B,EAAE,oCAAoC;gBAClE,SAAS,EAAE,SAAS;aACpB,CAAC,CAAC;SACH;KACD;IAED,MAAM,eAAe,GAAG,IAAI,CAAC;IA0B7B,IAAA,4BAAmB,EAClB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,CAAC,EACD,UAAU,EACV,eAAe,EACf,SAAS,CACT,CAAC;AACH,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnAfterDeath, hasOnDeath } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { debugState } from '../debug-state';\r\nimport { updateDivineShield } from '../keywords/divine-shield';\r\nimport { updateVenomous } from '../keywords/venomous';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { groupByFunction, pickRandom } from '../services/utils';\r\nimport { addImpliedMechanics, isBoardEntity, isFish } from '../utils';\r\nimport { applyAfterAttackEffects, applyAfterAttackTrinkets } from './after-attack';\r\nimport { onEntityDamaged } from './damage-effects';\r\nimport { rememberDeathrattles } from './deathrattle-effects';\r\nimport { orchestrateMinionDeathEffects } from './deathrattle-orchestration';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { makeMinionsDie } from './minion-death';\r\nimport { onMinionKill } from './minion-kill';\r\nimport { applyOnAttackEffects } from './on-attack';\r\nimport { applyOnBeingAttackedBuffs } from './on-being-attacked';\r\nimport { resolvePendingEffects } from './pending-effects';\r\nimport { performEntitySpawns } from './spawns';\r\nimport { applyAfterStatsUpdate } from './stats';\r\nimport { handleSummonsWhenSpace } from './summon-when-space';\r\nimport { canAttack } from './utils/entity-utils';\r\n\r\n// Only use it to simulate actual attack. To simulate damage, or something similar, use bumpInto\r\nexport const simulateAttack = (\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t\tforceTarget?: BoardEntity;\r\n\t},\r\n): BoardEntity => {\r\n\t// console.debug(\r\n\t// \t'\\nsimulating attack',\r\n\t// \tstringifySimple(attackingBoard, gameState.allCards),\r\n\t// \t'\\n',\r\n\t// \tstringifySimple(defendingBoard, gameState.allCards),\r\n\t// );\r\n\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst attackingEntity = getAttackingEntity(attackingBoard, attackingBoardHero, gameState.allCards);\r\n\tif (attackingEntity) {\r\n\t\tgameState.sharedState.currentAttackerEntityId = attackingEntity.entityId;\r\n\t\t// Get the left entities now, otherwise things might break if the attacker dies and/or other\r\n\t\t// entities pop\r\n\t\tconst attackingEntityIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\tconst attackingEntitiesToTheLeft = attackingBoard.slice(0, attackingEntityIndex);\r\n\t\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\t\t// In case of Broodmother spawn, it spawns where the dead minion was, and has no influence on the\r\n\t\t// attack order\r\n\t\t// Situation this is trying to resolve by putting this right at the top of the loop:\r\n\t\t// - One scallywag attacks into another one, both die\r\n\t\t// - The first one attacks. To its left is a Harmless Bonehead with 1 HP. The scallywag attacks, and both scallys die\r\n\t\t// - The *other* sky pirate attacks first, and kills the bonehead. Two minions are spawned\r\n\t\t// - The first sy pirate attacks\r\n\t\t// - The initial loop is resolved. If this is at the end, the Harmless Bonehead is already dead, and not flagged\r\n\t\t// While having this right away, we immediately flag all minions to the left\r\n\t\tif (!isAttackingImmediately) {\r\n\t\t\t// Make sure they won't be able to attack until everyone has attacked\r\n\t\t\t// See http://replays.firestoneapp.com/?reviewId=a1b3066d-e806-44c1-ab4b-7ef9dbf9b5b9&turn=5&action=4\r\n\t\t\tattackingEntitiesToTheLeft.forEach((entity) => (entity.hasAttacked = 2));\r\n\t\t\tattackingBoardHero.leftMostAttacked = 2;\r\n\t\t} else {\r\n\t\t\t// Change it right away so that new spawns don't trigger the \"attack immediately\" again\r\n\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t}\r\n\r\n\t\tconst numberOfAttacks = attackingEntity.windfury ? 2 : 1;\r\n\t\tfor (let i = 0; i < numberOfAttacks; i++) {\r\n\t\t\t// We refresh the entity in case of windfury\r\n\t\t\tif (attackingBoard.length === 0 || defendingBoard.length === 0) {\r\n\t\t\t\t// We still want to flag the entity as having attacked, so that it doesn't attack again\r\n\t\t\t\t// after teammate switch in Duos\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t// Check that didn't die\r\n\t\t\tif (attackingBoard.find((entity) => entity.entityId === attackingEntity.entityId)) {\r\n\t\t\t\tconst defendingEntity: BoardEntity =\r\n\t\t\t\t\toptions?.forceTarget ?? getDefendingEntity(defendingBoard, attackingEntity);\r\n\t\t\t\t// Can happen with a single defender that has stealth\r\n\t\t\t\tif (defendingEntity && defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tdoFullAttack(\r\n\t\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t\toptions,\r\n\t\t\t\t\t);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Solves the edge case of Sky Pirate vs a stealth board\r\n\t\t\t\t\tattackingEntity.attackImmediately = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tgameState.sharedState.currentAttackerEntityId = null;\r\n\t\tattackingEntity.hasAttacked = 1;\r\n\t\tattackingBoardHero.leftMostAttacked = 1;\r\n\t}\r\n\treturn attackingEntity;\r\n};\r\n\r\nexport const doFullAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\toptions?: {\r\n\t\tskipSummonWhenSpace?: boolean;\r\n\t},\r\n) => {\r\n\tconst isAttackingImmediately = attackingEntity.attackImmediately;\r\n\tgameState.spectator.registerAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tdefendingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoardHero,\r\n\t);\r\n\t// http://replays.firestoneapp.com/?reviewId=50576a9f-2e6a-4600-87ba-6e737ca9853e&turn=21&action=4\r\n\t// Looks like onBeingAttacked effects apply before onAttack effects\r\n\tapplyOnBeingAttackedBuffs(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker1, damageDoneByDefender: damageDoneByDefender1 } =\r\n\t\tapplyOnAttackEffects(\r\n\t\t\tattackingEntity,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\tconst { damageDoneByAttacker: damageDoneByAttacker2, damageDoneByDefender: damageDoneByDefender2 } = performAttack(\r\n\t\tattackingEntity,\r\n\t\tdefendingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t);\r\n\tconst damageDoneByAttacker = damageDoneByAttacker1 + damageDoneByAttacker2;\r\n\tconst damageDoneByDefender = damageDoneByDefender1 + damageDoneByDefender2;\r\n\r\n\t// Process this after the minions die and deathrattles are triggered/spawned\r\n\t// https://replays.firestoneapp.com/?reviewId=dd4e9dbe-abca-434a-ab94-04777cbedefe&turn=29&action=3\r\n\t// BUT: the attacking entity's afterAttack (like Macaw) needs to be processed\r\n\t// To recap:\r\n\t// - Jar o'Gems procs after the deathrattles have spawned\r\n\t// - When Monstrous Macaw procs a deathrattle, it is still on board, thus limiting the spawn room\r\n\t// So not sure what the exact timings are. It could be:\r\n\t// 1. Trigger minion's after attack\r\n\t// 2. Make minions die\r\n\t// 3. Process trinkets after attack\r\n\t// I have asked on Discord - for now I will consider a \"minion after attack\" phase and a \"trinket after attack\" phase.\r\n\t// I'm not sure about the secrets / trinkets, they will need to be adapted\r\n\t// The \"minion after attack\" phase seems to happen before the minions die:\r\n\t// https://replays.firestoneapp.com/?reviewId=ecdfab8d-e20e-4264-be4b-9cbe754118f7&turn=29&action=14\r\n\t// Here the Rally + Deathrattle minion attacks, but Deathstrider procs before it dies\r\n\tapplyAfterAttackEffects(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\r\n\tprocessMinionDeath(\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tgameState,\r\n\t\toptions?.skipSummonWhenSpace || isAttackingImmediately,\r\n\t);\r\n\r\n\tapplyAfterAttackTrinkets(\r\n\t\tattackingEntity,\r\n\t\tattackingBoard,\r\n\t\tattackingBoardHero,\r\n\t\tdefendingEntity,\r\n\t\tdefendingBoard,\r\n\t\tdefendingBoardHero,\r\n\t\tdamageDoneByAttacker,\r\n\t\tdamageDoneByDefender,\r\n\t\tgameState,\r\n\t);\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tattackingEntity.immuneWhenAttackCharges = Math.max(0, (attackingEntity.immuneWhenAttackCharges ?? 0) - 1);\r\n\t// if (\r\n\t// \tdefendingEntity.health > 0 &&\r\n\t// \t!defendingEntity.definitelyDead\r\n\t// \t&& (defendingEntity.cardId === CardIds.YoHoOgre_BGS_060 ||\r\n\t// \t\tdefendingEntity.cardId === CardIds.YoHoOgre_TB_BaconUps_150)\r\n\t// ) {\r\n\t// \tdefendingEntity.attackImmediately = true;\r\n\t// \tif (defendingEntity.attackImmediately) {\r\n\t// \t\tsimulateAttack(defendingBoard, defendingBoardHero, attackingBoard, attackingBoardHero, gameState);\r\n\t// \t}\r\n\t// }\r\n};\r\n\r\nconst performAttack = (\r\n\tattackingEntity: BoardEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): { damageDoneByAttacker: number; damageDoneByDefender: number } => {\r\n\tlet damageDoneByAttacker = 0;\r\n\tlet damageDoneByDefender = 0;\r\n\tconst hadVenomous = attackingEntity.venomous;\r\n\r\n\tif ([CardIds.BabyKrush_BG22_001, CardIds.BabyKrush_BG22_001_G].includes(attackingEntity.cardId as CardIds)) {\r\n\t\tconst spawns = spawnEntities(\r\n\t\t\tattackingEntity.cardId === CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t? CardIds.BabyKrush_BG22_001_G\r\n\t\t\t\t: CardIds.BabyKrush_DevilsaurToken,\r\n\t\t\t1,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tgameState,\r\n\t\t\ttrue,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t\tif (spawns.length > 0) {\r\n\t\t\tconst sourceIndex = attackingBoard.indexOf(attackingEntity);\r\n\t\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\t\tspawns,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tsourceIndex,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tfor (const actualSpawn of actualSpawns) {\r\n\t\t\t\tif (defendingEntity.health > 0 && !defendingEntity.definitelyDead) {\r\n\t\t\t\t\tperformAttack(\r\n\t\t\t\t\t\tactualSpawn,\r\n\t\t\t\t\t\tdefendingEntity,\r\n\t\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\t\tgameState,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// For Prestor\r\n\tconst defenderAliveBeforeAttack = defendingEntity.health > 0 && !defendingEntity.definitelyDead;\r\n\t// Because of Bristleback Knight, which changes its divine shield status during bumpEntities\r\n\tconst attackerHadDivineShield = attackingEntity.divineShield;\r\n\tconst defenderHadDivineShield = defendingEntity.divineShield;\r\n\t// For cleave\r\n\t// We do that now so that we don't include entities that spawn on entity damaged\r\n\tconst defenderNeighbours: readonly BoardEntity[] = getNeighbours(defendingBoard, defendingEntity);\r\n\tif (defenderAliveBeforeAttack) {\r\n\t\tif (!attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\t// TODO: this bumpEntities approach doesn't work well, as it leads to code duplication\r\n\t\t\tdamageDoneByDefender += bumpEntities(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tdamageDoneByAttacker += bumpEntities(\r\n\t\t\tdefendingEntity,\r\n\t\t\tattackingEntity,\r\n\t\t\tdefendingBoard,\r\n\t\t\tdefendingBoardHero,\r\n\t\t\tattackingBoard,\r\n\t\t\tattackingBoardHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tif (defendingEntity.attack > 0 && attackerHadDivineShield && !attackingEntity.immuneWhenAttackCharges) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (attackingEntity.attack > 0 && defenderHadDivineShield) {\r\n\t\t\tupdateDivineShield(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tfalse,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// This whole logic is a MEEEEESSSSSSSSSSSSSSS\r\n\t\tif (damageDoneByDefender > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdamageDoneByDefender,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (damageDoneByAttacker > 0) {\r\n\t\t\tonEntityDamaged(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdamageDoneByAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tif (defendingEntity.health <= 0 || defendingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\thadVenomous,\r\n\t\t\t\ttrue,\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t\tif (attackingEntity.health <= 0 || attackingEntity.definitelyDead) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\tdefendingEntity,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tdefenderNeighbours,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t}\r\n\t// Cleave\r\n\tif (attackingEntity.cleave) {\r\n\t\tfor (const neighbour of defenderNeighbours) {\r\n\t\t\tconst thisAttackDamage = bumpEntities(\r\n\t\t\t\tneighbour,\r\n\t\t\t\tattackingEntity,\r\n\t\t\t\tdefendingBoard,\r\n\t\t\t\tdefendingBoardHero,\r\n\t\t\t\tattackingBoard,\r\n\t\t\t\tattackingBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\ttrue,\r\n\t\t\t\thadVenomous,\r\n\t\t\t);\r\n\t\t\tdamageDoneByAttacker += thisAttackDamage;\r\n\t\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t\t// cause wrong results to happen\r\n\t\t\tif (attackingEntity.attack > 0 && neighbour.divineShield) {\r\n\t\t\t\tupdateDivineShield(neighbour, defendingBoard, defendingBoardHero, attackingBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (thisAttackDamage > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\tthisAttackDamage,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\tif (neighbour.health <= 0 || neighbour.definitelyDead) {\r\n\t\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onMinionKill(\r\n\t\t\t\t\tattackingEntity,\r\n\t\t\t\t\thadVenomous,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tneighbour,\r\n\t\t\t\t\tattackingBoard,\r\n\t\t\t\t\tattackingBoardHero,\r\n\t\t\t\t\tdefendingBoard,\r\n\t\t\t\t\tdefendingBoardHero,\r\n\t\t\t\t\tdefenderNeighbours,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tattackingEntity.attackImmediately = false;\r\n\tif (attackingEntity.enchantments.some((e) => e.cardId === CardIds.VolatileVenom_VolatileEnchantment)) {\r\n\t\tattackingEntity.definitelyDead = true;\r\n\t}\r\n\treturn { damageDoneByAttacker, damageDoneByDefender };\r\n};\r\n\r\n// TODO: Could it be possible to store the index of the entity that last attacked? Probably not, because minion\r\n// spawns would mess this up? Could we update the indexes as each entity spawns / dies?\r\nconst getAttackingEntity = (\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n): BoardEntity => {\r\n\tlet validAttackers = attackingBoard.filter((entity) => canAttack(entity));\r\n\tif (validAttackers.length === 0) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tif (validAttackers.some((entity) => entity.attackImmediately)) {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.attackImmediately);\r\n\t} else if (validAttackers.every((e) => e.hasAttacked != null)) {\r\n\t\tattackingBoard.forEach((e) => (e.hasAttacked = undefined));\r\n\t\tattackingBoardHero.leftMostAttacked = undefined;\r\n\t} else {\r\n\t\tvalidAttackers = validAttackers.filter((entity) => entity.hasAttacked == undefined);\r\n\t}\r\n\tconst attacker = validAttackers[0];\r\n\treturn attacker;\r\n};\r\n\r\nexport const findNearestEnemies = (\r\n\tattackingBoard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tentityIndexFromRight: number,\r\n\tdefendingBoard: BoardEntity[],\r\n\tnumberOfTargets: number,\r\n\tallCards: AllCardsService,\r\n): BoardEntity[] => {\r\n\tconst result = [];\r\n\tif (defendingBoard.length > 0) {\r\n\t\t// console.debug('defending board', numberOfTargets, stringifySimple(defendingBoard, allCards));\r\n\t\tconst attackerIndex = attackingBoard.length - entityIndexFromRight - 1;\r\n\t\tconst targetIndex = attackerIndex - (attackingBoard.length - defendingBoard.length) / 2;\r\n\t\t// console.debug('indexes', attackerIndex, entityIndexFromRight, targetIndex, attackingBoard.length);\r\n\r\n\t\tfor (let i = 0; i < numberOfTargets; i++) {\r\n\t\t\tconst possibleTargets = defendingBoard\r\n\t\t\t\t.filter((e) => !e.definitelyDead && e.health > 0)\r\n\t\t\t\t.filter((e) => !result.includes(e));\r\n\t\t\t// console.debug('possibleTargets', stringifySimple(possibleTargets, allCards));\r\n\t\t\tif (!possibleTargets.length) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tconst targetGroups = groupByFunction((e: BoardEntity) => Math.abs(defendingBoard.indexOf(e) - targetIndex))(\r\n\t\t\t\tpossibleTargets,\r\n\t\t\t);\r\n\t\t\tconst distances = Object.keys(targetGroups)\r\n\t\t\t\t.map((k) => +k)\r\n\t\t\t\t.sort();\r\n\t\t\tconst nearestDistance = distances[0];\r\n\t\t\tif (nearestDistance != null) {\r\n\t\t\t\t// console.debug(\r\n\t\t\t\t// \t'targetGroups[nearestDistance]',\r\n\t\t\t\t// \tnearestDistance,\r\n\t\t\t\t// \tstringifySimple(targetGroups[nearestDistance], allCards),\r\n\t\t\t\t// );\r\n\t\t\t\tconst target = pickRandom(targetGroups[nearestDistance]);\r\n\t\t\t\tresult.push(target);\r\n\t\t\t}\r\n\t\t\t// console.debug('\\n');\r\n\t\t}\r\n\t}\r\n\treturn result.filter((e) => !!e);\r\n};\r\n\r\nexport const getNeighbours = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n\talwaysIncludeBoth = false,\r\n): readonly BoardEntity[] => {\r\n\tconst neighbours = [];\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\tneighbours.push(leftNeighbour);\r\n\t\t}\r\n\r\n\t\t// If the deadEntityIndexFromRight === 0 (right-most minion), no neighbour will be found\r\n\t\tconst rightNeighbourIndex = board.length - 1 - (deadEntityIndexFromRight - 1);\r\n\t\tconst rightNeighbour = board[rightNeighbourIndex];\r\n\t\tif (rightNeighbour) {\r\n\t\t\tneighbours.push(rightNeighbour);\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\tneighbours.push(board[index - 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t\t// neighbours.push(entity);\r\n\t\tif (index + 1 < board.length) {\r\n\t\t\tneighbours.push(board[index + 1]);\r\n\t\t} else if (alwaysIncludeBoth) {\r\n\t\t\tneighbours.push(null);\r\n\t\t}\r\n\t}\r\n\treturn neighbours;\r\n};\r\n\r\nexport const getLeftNeighbour = (\r\n\tboard: BoardEntity[],\r\n\tentity: BoardEntity,\r\n\tdeadEntityIndexFromRight?: number,\r\n): BoardEntity => {\r\n\t// When triggering DR with Hawkstrider, the entity is still on the board\r\n\tif (deadEntityIndexFromRight != null && !board.includes(entity)) {\r\n\t\tconst leftNeighbourIndex = board.length - 1 - deadEntityIndexFromRight;\r\n\t\tconst leftNeighbour = board[leftNeighbourIndex];\r\n\t\tif (leftNeighbour) {\r\n\t\t\treturn leftNeighbour;\r\n\t\t}\r\n\t} else {\r\n\t\tconst index = board.findIndex((e) => e.entityId === entity.entityId);\r\n\t\tif (index - 1 >= 0) {\r\n\t\t\treturn board[index - 1];\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\nexport const dealDamageToRandomEnemy = (\r\n\tboardToBeDamaged: BoardEntity[],\r\n\tboardToBeDamagedHero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity,\r\n\tdamage: number,\r\n\tboardWithAttackOrigin: BoardEntity[],\r\n\tboardWithAttackOriginHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (boardToBeDamaged.length === 0) {\r\n\t\treturn;\r\n\t}\r\n\tconst validTargets = boardToBeDamaged.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst defendingEntity: BoardEntity = pickRandom(validTargets);\r\n\tif (defendingEntity) {\r\n\t\tgameState.spectator.registerPowerTarget(\r\n\t\t\tdamageSource,\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t);\r\n\t\tdealDamageToMinion(\r\n\t\t\tdefendingEntity,\r\n\t\t\tboardToBeDamaged,\r\n\t\t\tboardToBeDamagedHero,\r\n\t\t\tdamageSource,\r\n\t\t\tdamage,\r\n\t\t\tboardWithAttackOrigin,\r\n\t\t\tboardWithAttackOriginHero,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n};\r\n\r\nexport const dealDamageToMinion = (\r\n\ttarget: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!target) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst isDeadBeforeDamage = target.definitelyDead || target.health <= 0;\r\n\tconst hadVenomous = (damageSource as BoardEntity).venomous;\r\n\tconst spawns = [];\r\n\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t// without it\r\n\tconst fakeAttacker = {\r\n\t\t...(damageSource || {}),\r\n\t\tentityId: -1,\r\n\t\tattack: damage,\r\n\t\t// attacking: true,\r\n\t} as BoardEntity;\r\n\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\r\n\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t// cause wrong results to happen\r\n\t// TODO: why isn't it done in bumpEntities?\r\n\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t// the divine shield once both bumps are done\r\n\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t}\r\n\r\n\tif (actualDamageDone > 0) {\r\n\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\ttarget,\r\n\t\t\tboard,\r\n\t\t\thero,\r\n\t\t\totherBoard,\r\n\t\t\totherHero,\r\n\t\t\tdamageSource,\r\n\t\t\tactualDamageDone,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t}\r\n\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\tonMinionKill(\r\n\t\t\t\tdamageSource as BoardEntity,\r\n\t\t\t\thadVenomous,\r\n\t\t\t\tfalse,\r\n\t\t\t\ttarget,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\t[],\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\tif (actualDamageDone > 0) {\r\n\t\tif (isBoardEntity(damageSource)) {\r\n\t\t\tdamageSource.venomous = false;\r\n\t\t}\r\n\t}\r\n\tconst defendingEntityIndex = board.findIndex((entity) => entity.entityId === target.entityId);\r\n\tboard[defendingEntityIndex] = target;\r\n\treturn actualDamageDone;\r\n};\r\n\r\n// Because the \"onEntityDamaged\" effect is only called once all the minions are damaged\r\nexport const dealDamageToMinions = (\r\n\ttargets: BoardEntity[],\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tdamageSource: BoardEntity | BgsPlayerEntity,\r\n\tdamage: number,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\t// console.log('dealing damage to', damage, stringifySimpleCard(defendingEntity, allCards));\r\n\tif (!targets?.length) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst actualDamagesDone = [];\r\n\tconst areDeadBeforeDamage = targets.map((target) => target.definitelyDead || target.health <= 0);\r\n\tconst hadVenomous = (damageSource as BoardEntity).venomous;\r\n\r\n\tfor (const target of targets) {\r\n\t\t// Why do we use a fakeAttacker? Is that for the \"attacking\" prop?\r\n\t\t// That prop is only used for Overkill, and even in that case it looks like it would work\r\n\t\t// without it\r\n\t\tconst fakeAttacker = {\r\n\t\t\t...(damageSource || {}),\r\n\t\t\tentityId: -1,\r\n\t\t\tattack: damage,\r\n\t\t\t// attacking: true,\r\n\t\t} as BoardEntity;\r\n\t\tconst actualDamageDone = bumpEntities(target, fakeAttacker, board, hero, otherBoard, otherHero, gameState);\r\n\t\tactualDamagesDone.push(actualDamageDone);\r\n\r\n\t\t// Do it after the damage has been done, so that entities that update on DS lose / gain (CyborgDrake) don't\r\n\t\t// cause wrong results to happen\r\n\t\t// TODO: why isn't it done in bumpEntities?\r\n\t\t// Because of how \"bump\" works: we do it first for the attacker, then the defender, and we only want to update\r\n\t\t// the divine shield once both bumps are done\r\n\t\t// The problem is with the Frenzy: bumpEntities can trigger the frenzy, and which can act on the divine shield\r\n\t\tif (fakeAttacker.attack > 0 && target.divineShield) {\r\n\t\t\tupdateDivineShield(target, board, hero, otherHero, false, gameState);\r\n\t\t}\r\n\t}\r\n\r\n\tconst spawns = [];\r\n\tfor (let i = 0; i < targets.length; i++) {\r\n\t\tconst target = targets[i];\r\n\t\tconst actualDamageDone = actualDamagesDone[i];\r\n\t\tconst isDeadBeforeDamage = areDeadBeforeDamage[i];\r\n\t\tif (actualDamageDone > 0) {\r\n\t\t\t// TODO: handle entities that have been spawned here to adjust the dead entity index from parent stack\r\n\t\t\tconst newSpawns = onEntityDamaged(\r\n\t\t\t\ttarget,\r\n\t\t\t\tboard,\r\n\t\t\t\thero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tdamageSource,\r\n\t\t\t\tactualDamageDone,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t}\r\n\t\tif (!isDeadBeforeDamage && actualDamageDone > 0 && 'attack' in damageSource && 'health' in damageSource) {\r\n\t\t\ttarget.lastAffectedByEntity = damageSource as BoardEntity;\r\n\r\n\t\t\tif (target.health <= 0 || target.definitelyDead) {\r\n\t\t\t\tonMinionKill(\r\n\t\t\t\t\tdamageSource as BoardEntity,\r\n\t\t\t\t\thadVenomous,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\ttarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tboard,\r\n\t\t\t\t\thero,\r\n\t\t\t\t\t[],\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t\tconst defendingEntityIndex = board.map((entity) => entity.entityId).indexOf(target.entityId);\r\n\t\tboard[defendingEntityIndex] = target;\r\n\t}\r\n\treturn actualDamagesDone.reduce((a, b) => a + b, 0);\r\n};\r\n\r\nexport const getDefendingEntity = (\r\n\tdefendingBoard: BoardEntity[],\r\n\tattackingEntity: BoardEntity,\r\n\tignoreTaunts = false,\r\n): BoardEntity => {\r\n\tif (debugState.active) {\r\n\t\tfor (const forcedFaceOff of debugState.forcedFaceOff) {\r\n\t\t\tif (debugState.isCorrectEntity(forcedFaceOff.attacker, attackingEntity)) {\r\n\t\t\t\t// if (attackingEntity.entityId === forcedFaceOff.attacker.entityId) {\r\n\t\t\t\tconst def = defendingBoard.find((e) => debugState.isCorrectEntity(forcedFaceOff.defender, e));\r\n\t\t\t\tif (!!def) {\r\n\t\t\t\t\t// Remove the face-off\r\n\t\t\t\t\tdebugState.forcedFaceOff = debugState.forcedFaceOff.filter((f) => f != forcedFaceOff);\r\n\t\t\t\t\treturn def;\r\n\t\t\t\t}\r\n\t\t\t\t// }\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tlet possibleDefenders: readonly BoardEntity[];\r\n\tif (\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_BGS_022 ||\r\n\t\tattackingEntity.cardId === CardIds.ZappSlywick_TB_BaconUps_091 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845 ||\r\n\t\tattackingEntity.cardId === CardIds.MercilessMammoth_BG33_845_G\r\n\t) {\r\n\t\tconst minAttack = Math.min(...defendingBoard.map((entity) => entity.attack));\r\n\t\tpossibleDefenders = defendingBoard.filter((entity) => entity.attack === minAttack);\r\n\t} else if (\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921 ||\r\n\t\tattackingEntity.cardId === CardIds.WorgenVigilante_BG26_921_G\r\n\t) {\r\n\t\tpossibleDefenders = defendingBoard\r\n\t\t\t.filter(\r\n\t\t\t\t(entity) =>\r\n\t\t\t\t\tentity.health <= attackingEntity.attack || attackingEntity.venomous || attackingEntity.poisonous,\r\n\t\t\t)\r\n\t\t\t.filter((e) => !e.divineShield);\r\n\t\tif (!possibleDefenders.length) {\r\n\t\t\tpossibleDefenders = defendingBoard;\r\n\t\t}\r\n\t} else {\r\n\t\tpossibleDefenders = defendingBoard.filter((e) => !e.stealth);\r\n\t\tif (!ignoreTaunts) {\r\n\t\t\tconst taunts = possibleDefenders.filter((entity) => entity.taunt);\r\n\t\t\tpossibleDefenders = taunts.length > 0 ? taunts : possibleDefenders;\r\n\t\t}\r\n\t}\r\n\r\n\tconst chosenDefender = pickRandom(possibleDefenders);\r\n\t// if (chosenDefender?.taunt) {\r\n\t// \tconst elistras = defendingBoard.filter(\r\n\t// \t\t(entity) =>\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_BGS_205 ||\r\n\t// \t\t\tentity.cardId === CardIds.ElistraTheImmortal_TB_BaconUps_306,\r\n\t// \t);\r\n\t// \tif (elistras.length > 0) {\r\n\t// \t\tchosenDefender = elistras[Math.floor(Math.random() * elistras.length)];\r\n\t// \t}\r\n\t// }\r\n\treturn chosenDefender;\r\n};\r\n\r\nexport const bumpEntities = (\r\n\tentity: BoardEntity,\r\n\tbumpInto: BoardEntity,\r\n\tentityBoard: BoardEntity[],\r\n\tentityBoardHero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tapplyVenomous = true,\r\n\tforceVenomous = false,\r\n): number => {\r\n\t// No attack has no impact\r\n\tconst debug = bumpInto.cardId === 'BG26_888';\r\n\tif (bumpInto.attack === 0) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\t// Matador effect has priority\r\n\tif (\r\n\t\tentity.abiityChargesLeft > 0 &&\r\n\t\t(entity.cardId === CardIds.MadMatador_BG28_404 || entity.cardId === CardIds.MadMatador_BG28_404_G)\r\n\t) {\r\n\t\tentity.abiityChargesLeft--;\r\n\t\tconst newTarget = pickRandom(otherBoard);\r\n\t\tif (newTarget) {\r\n\t\t\tgameState.spectator.registerPowerTarget(entity, newTarget, otherBoard, entityBoardHero, otherHero);\r\n\t\t\t// TODO: here the MadMatador is the source of the damage, not the initial attacker\r\n\t\t\t// Not sure exactly what the impact would be, as there is no counter\r\n\t\t\tconst newSource = {\r\n\t\t\t\t...entity,\r\n\t\t\t\tattack: bumpInto.attack,\r\n\t\t\t\t// attacking: true,\r\n\t\t\t} as BoardEntity;\r\n\t\t\tconst defenderHadDivineShield = newTarget.divineShield;\r\n\t\t\tconst damageDone = bumpEntities(\r\n\t\t\t\tnewTarget,\r\n\t\t\t\tnewSource,\r\n\t\t\t\totherBoard,\r\n\t\t\t\totherHero,\r\n\t\t\t\tentityBoard,\r\n\t\t\t\tentityBoardHero,\r\n\t\t\t\tgameState,\r\n\t\t\t\tfalse,\r\n\t\t\t);\r\n\t\t\tif (newSource.attack > 0 && defenderHadDivineShield) {\r\n\t\t\t\tupdateDivineShield(newTarget, otherBoard, otherHero, entityBoardHero, false, gameState);\r\n\t\t\t}\r\n\t\t\tif (damageDone > 0) {\r\n\t\t\t\tonEntityDamaged(\r\n\t\t\t\t\tnewTarget,\r\n\t\t\t\t\totherBoard,\r\n\t\t\t\t\totherHero,\r\n\t\t\t\t\tentityBoard,\r\n\t\t\t\t\tentityBoardHero,\r\n\t\t\t\t\tnewSource,\r\n\t\t\t\t\tdamageDone,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t\treturn damageDone;\r\n\t\t}\r\n\t}\r\n\r\n\tif (entity.divineShield) {\r\n\t\tgameState.spectator.registerDamageDealt(bumpInto, entity, 0, entityBoard);\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tconst damageDealt = (entity.damageMultiplier || 1) * bumpInto.attack;\r\n\tentity.health = entity.health - damageDealt;\r\n\t// FIXME: This will likely be incorrect in terms of timings, e.g. if the entity ends up\r\n\t// surviving following a buff like Spawn.\r\n\tgameState.spectator.registerDamageDealt(bumpInto, entity, damageDealt, entityBoard);\r\n\r\n\t// if (entity.cardId === CardIds.Bubblette_BG_TID_713 && bumpInto.attack === 1) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// } else if (entity.cardId === CardIds.Bubblette_BG_TID_713_G && bumpInto.attack === 2) {\r\n\t// \tentity.definitelyDead = true;\r\n\t// }\r\n\t// Do it last, so that other effects are still processed\r\n\tif (bumpInto.poisonous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t}\r\n\tif ((bumpInto.venomous || forceVenomous) && applyVenomous) {\r\n\t\t// So that further buffs don't revive it\r\n\t\t// And we don't just set the health to avoid applying overkill effects\r\n\t\tentity.definitelyDead = true;\r\n\t\tupdateVenomous(bumpInto, false, otherBoard, otherHero, entityBoardHero, gameState);\r\n\t}\r\n\t// Ideally we should do the Reckoning stuff here. However, at this point we only have half the damage\r\n\t// information, so it is possible that the entity deals more than 3 (which should trigger Reckoning)\r\n\t// but dies during the exchange (and Reckoning doesn't trigger then)\r\n\r\n\tentity.lastAffectedByEntity = bumpInto;\r\n\t// if (entity.frenzyChargesLeft > 0 && entity.health > 0 && !entity.definitelyDead) {\r\n\t// \tapplyFrenzy(entity, entityBoard, entityBoardHero, gameState);\r\n\t// \tentity.frenzyChargesLeft--;\r\n\t// }\r\n\r\n\t// We spawn them here, because it says \"whenever\", and so happens right away\r\n\t// FIXME: there could be a bug here, if a Cleave attacks several IGB at the same time. The current\r\n\t// implementation could spawn minions above the max board size. Fringe case though, so leaving it\r\n\t// like this for now\r\n\t// const entitySpawns = getWheneverEntitySpawns(\r\n\t// \tentity,\r\n\t// \tentityBoard,\r\n\t// \tentityBoardHero,\r\n\t// \totherBoard,\r\n\t// \totherHero,\r\n\t// \tgameState.allCards,\r\n\t// \tgameState.cardsData,\r\n\t// \tgameState.sharedState,\r\n\t// \tgameState.spectator,\r\n\t// );\r\n\t// if (!!entitySpawns?.length) {\r\n\t// \t// Spawn to the right\r\n\t// \tconst index = entityBoard.map((e) => e.entityId).indexOf(entity.entityId) + 1;\r\n\t// \taddMinionsToBoard(entityBoard, entityBoardHero, otherHero, index, entitySpawns, gameState);\r\n\t// \tgameState.spectator.registerMinionsSpawn(entity, entityBoard, entitySpawns);\r\n\t// }\r\n\treturn bumpInto.attack;\r\n};\r\n\r\n// const getWheneverEntitySpawns = (\r\n// \tentity: BoardEntity,\r\n// \tentityBoard: BoardEntity[],\r\n// \tentityBoardHero: BgsPlayerEntity,\r\n// \totherBoard: BoardEntity[],\r\n// \totherHero: BgsPlayerEntity,\r\n// \tallCards: AllCardsService,\r\n// \tcardsData: CardsData,\r\n// \tsharedState: SharedState,\r\n// \tspectator: Spectator,\r\n// ): readonly BoardEntity[] => {\r\n// \tif (entityBoard.length === 7) {\r\n// \t\treturn null;\r\n// \t}\r\n\r\n// \tif (entity.cardId === CardIds.ImpGangBoss_BRM_006) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_BRM_006t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpGangBoss_TB_BaconUps_030) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.ImpGangBoss_ImpToken_TB_BaconUps_030t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.ImpMama_BGS_044) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.ImpMama_TB_BaconUps_116) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tcardsData.impMamaSpawns[Math.floor(Math.random() * cardsData.impMamaSpawns.length)],\r\n// \t\t\t2,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t).map((entity) => ({ ...entity, taunt: true }));\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_BOT_218) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_BOT_218t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t} else if (entity.cardId === CardIds.SecurityRover_TB_BaconUps_041) {\r\n// \t\treturn spawnEntities(\r\n// \t\t\tCardIds.SecurityRover_GuardBotToken_TB_BaconUps_041t,\r\n// \t\t\t1,\r\n// \t\t\tentityBoard,\r\n// \t\t\tentityBoardHero,\r\n// \t\t\totherBoard,\r\n// \t\t\totherHero,\r\n// \t\t\tallCards,\r\n// \t\t\tcardsData,\r\n// \t\t\tsharedState,\r\n// \t\t\tspectator,\r\n// \t\t\tentity.friendly,\r\n// \t\t\ttrue,\r\n// \t\t);\r\n// \t}\r\n// \treturn null;\r\n// };\r\n\r\nexport const processMinionDeath = (\r\n\tboard1: BoardEntity[],\r\n\tboard1Hero: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tboard2Hero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\t// When we're in an \"attack immediately\" phase, we wait until we're out of the phase to summon minions\r\n\tskipSummonWhenSpace = false,\r\n): void => {\r\n\t// const debug = board1.some((e) => e.health <= 0) || board2.some((e) => e.health <= 0);\r\n\t// debug && console.debug('\\nprocessing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\tconst [deadMinionIndexesFromLeft1, deadMinionIndexesFromRights1, deadEntities1] = makeMinionsDie(\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\tconst [deadMinionIndexesFromLeft2, deadMinionIndexesFromRights2, deadEntities2] = makeMinionsDie(\r\n\t\tboard2,\r\n\t\tboard2Hero,\r\n\t\tboard1,\r\n\t\tboard1Hero,\r\n\t\tgameState,\r\n\t);\r\n\t// debug && console.debug('after processing minions death');\r\n\t// debug && console.debug(stringifySimple(board1, gameState.allCards));\r\n\t// debug && console.debug(stringifySimple(board2, gameState.allCards));\r\n\t// debug && console.debug(deadMinionIndexesFromRights1);\r\n\t// debug && console.debug(deadMinionIndexesFromRights2);\r\n\t// console.debug('dead entities', stringifySimple(deadEntities1, allCards), stringifySimple(deadEntities2, allCards));\r\n\t// No death to process, we can return\r\n\tif (deadEntities1.length === 0 && deadEntities2.length === 0) {\r\n\t\treturn;\r\n\t\t// return [board1, board2];\r\n\t}\r\n\r\n\t// Remember them right away, so that subsequent deaths do not break the order\r\n\t// TODO: move this to the deathrattle-orchestration?\r\n\t// If the fish dies (from Scallywag for instance), it doesn't remember the deathrattle\r\n\t// console.debug(\r\n\t// \t'\\n\\ndeadEntities',\r\n\t// \tstringifySimple(deadEntities1, gameState.allCards),\r\n\t// \tstringifySimple(deadEntities2, gameState.allCards),\r\n\t// );\r\n\r\n\tgameState.spectator.registerDeadEntities(\r\n\t\tdeadMinionIndexesFromRights1,\r\n\t\tdeadEntities1,\r\n\t\tboard1,\r\n\t\tdeadMinionIndexesFromRights2,\r\n\t\tdeadEntities2,\r\n\t\tboard2,\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities1.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft1[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\tgameState.sharedState.deaths.push(\r\n\t\t...deadEntities2.map((e, index) =>\r\n\t\t\taddImpliedMechanics(\r\n\t\t\t\t{\r\n\t\t\t\t\t...e,\r\n\t\t\t\t\thealth: e.maxHealth,\r\n\t\t\t\t\tdefinitelyDead: false,\r\n\t\t\t\t\tindexFromLeftAtTimeOfDeath: deadMinionIndexesFromLeft2[index],\r\n\t\t\t\t},\r\n\t\t\t\tgameState.cardsData,\r\n\t\t\t),\r\n\t\t),\r\n\t);\r\n\r\n\tfor (const deadEntity of deadEntities1) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board1Hero,\r\n\t\t\t\tboard: board1,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const deadEntity of deadEntities2) {\r\n\t\tconst onDeathImpl = cardMappings[deadEntity.cardId];\r\n\t\tif (hasOnDeath(onDeathImpl)) {\r\n\t\t\tonDeathImpl.onDeath(deadEntity, {\r\n\t\t\t\thero: board2Hero,\r\n\t\t\t\tboard: board2,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tboard1Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard1Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities1.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\tboard2Hero.globalInfo.EternalKnightsDeadThisGame =\r\n\t\tboard2Hero.globalInfo.EternalKnightsDeadThisGame +\r\n\t\tdeadEntities2.filter(\r\n\t\t\t(e) => e.cardId === CardIds.EternalKnight_BG25_008 || e.cardId === CardIds.EternalKnight_BG25_008_G,\r\n\t\t).length;\r\n\r\n\torchestrateMinionDeathEffects({\r\n\t\tgameState: gameState,\r\n\t\tplayerDeadEntities: board1Hero.friendly ? deadEntities1 : deadEntities2,\r\n\t\tplayerDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights1\r\n\t\t\t: deadMinionIndexesFromRights2,\r\n\t\topponentDeadEntities: board1Hero.friendly ? deadEntities2 : deadEntities1,\r\n\t\topponentDeadEntityIndexesFromRight: board1Hero.friendly\r\n\t\t\t? deadMinionIndexesFromRights2\r\n\t\t\t: deadMinionIndexesFromRights1,\r\n\t});\r\n\r\n\t// Make sure we only return when there are no more deaths to process\r\n\t// Make sure to do this right before the end of the process\r\n\t// FIXME: this will propagate the killer between rounds, which is incorrect. For instance,\r\n\t// if a dragon kills a Ghoul, then the Ghoul's deathrattle kills a Kaboom, the killer should\r\n\t// now be the ghoul. Then if the Kaboom kills someone, the killer should again change. You could\r\n\t// also have multiple killers, which is not taken into account here.\r\n\t// The current assumption is that it's a suffienctly fringe case to not matter too much\r\n\tprocessMinionDeath(board1, board1Hero, board2, board2Hero, gameState);\r\n\r\n\t// Not sure about the timing here, but I have bothered Mitchell quite a lot already recently :)\r\n\tif (!skipSummonWhenSpace) {\r\n\t\thandleSummonsWhenSpace(board1, board1Hero, board2, board2Hero, gameState);\r\n\t}\r\n\r\n\t// Apply \"after minion death\" effects\r\n\thandleAfterMinionsDeaths(\r\n\t\tboard1,\r\n\t\tdeadEntities1,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights1 : deadMinionIndexesFromRights2,\r\n\t\tboard1Hero,\r\n\t\tboard2,\r\n\t\tdeadEntities2,\r\n\t\tboard1Hero.friendly ? deadMinionIndexesFromRights2 : deadMinionIndexesFromRights1,\r\n\t\tboard2Hero,\r\n\t\tgameState,\r\n\t);\r\n\r\n\t// Only when all deathrattles have resolved\r\n\t// 2025-12-20: https://replays.firestoneapp.com/?reviewId=7d8f9af4-b484-4256-976b-ff9df8847b50&turn=5&action=0\r\n\t// Confirmed by dev that the fish doesn't get the deathrattle in this case\r\n\tboard1\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities1, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\tboard2\r\n\t\t.filter((entity) => isFish(entity))\r\n\t\t.forEach((entity) =>\r\n\t\t\trememberDeathrattles(entity, deadEntities2, gameState.cardsData, gameState.allCards, gameState.sharedState),\r\n\t\t);\r\n\r\n\tresolvePendingEffects(board1, board1Hero, board2, board2Hero, gameState);\r\n};\r\n\r\nconst handleAfterMinionsDeaths = (\r\n\tboard1: BoardEntity[],\r\n\tdeadEntities1: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight1: number[],\r\n\theroEntity1: BgsPlayerEntity,\r\n\tboard2: BoardEntity[],\r\n\tdeadEntities2: BoardEntity[],\r\n\tdeadEntitiesIndexesFromRight2: number[],\r\n\theroEntity2: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst random = Math.random() > 0.5;\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\trandom ? board1 : board2,\r\n\t\trandom ? deadEntities1 : deadEntities2,\r\n\t\trandom ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\trandom ? heroEntity1 : heroEntity2,\r\n\t\trandom ? board2 : board1,\r\n\t\trandom ? deadEntities2 : deadEntities1,\r\n\t\trandom ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\trandom ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n\thandleAfterMinionsDeathsForBoard(\r\n\t\t!random ? board1 : board2,\r\n\t\t!random ? deadEntities1 : deadEntities2,\r\n\t\t!random ? deadEntitiesIndexesFromRight1 : deadEntitiesIndexesFromRight2,\r\n\t\t!random ? heroEntity1 : heroEntity2,\r\n\t\t!random ? board2 : board1,\r\n\t\t!random ? deadEntities2 : deadEntities1,\r\n\t\t!random ? deadEntitiesIndexesFromRight2 : deadEntitiesIndexesFromRight1,\r\n\t\t!random ? heroEntity2 : heroEntity1,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nconst handleAfterMinionsDeathsForBoard = (\r\n\tfriendlyBoard: BoardEntity[],\r\n\tfriendlyDeadEntities: BoardEntity[],\r\n\tfriendlyDeadEntitiesIndexesFromRight: number[],\r\n\tfriendlyHeroEntity: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherDeadEntities: BoardEntity[],\r\n\totherDeadEntitiesIndexesFromRight: number[],\r\n\totherHeroEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst candidateEntities = [];\r\n\r\n\tfor (const trinket of friendlyHeroEntity.trinkets ?? []) {\r\n\t\tconst onAfterDeathImpl = cardMappings[trinket.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(trinket, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tfor (const entity of friendlyBoard) {\r\n\t\tconst onAfterDeathImpl = cardMappings[entity.cardId];\r\n\t\tif (hasOnAfterDeath(onAfterDeathImpl)) {\r\n\t\t\tonAfterDeathImpl.onAfterDeath(entity, {\r\n\t\t\t\thero: friendlyHeroEntity,\r\n\t\t\t\tboard: friendlyBoard,\r\n\t\t\t\totherHero: otherHeroEntity,\r\n\t\t\t\totherBoard: otherBoard,\r\n\t\t\t\tdeadEntities: friendlyDeadEntities,\r\n\t\t\t\tdeadEntitiesIndexesFromRight: friendlyDeadEntitiesIndexesFromRight,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tconst secretTriggered = null;\r\n\t// if (\r\n\t// \t(secretTriggered = friendlyHeroEntity.secrets?.find(\r\n\t// \t\t(secret) => !secret.triggered && secret?.cardId === CardIds.MagicBlackSoulstone,\r\n\t// \t)) != null\r\n\t// ) {\r\n\t// \tif (friendlyBoard.length === 0) {\r\n\t// \t\tsecretTriggered.triggered = true;\r\n\t// \t\tfor (let i = 0; i < 2; i++) {\r\n\t// \t\t\tconst toSummon = pickRandom(gameState.cardsData.demonSpawns);\r\n\t// \t\t\tcandidateEntities.push(\r\n\t// \t\t\t\t...spawnEntities(\r\n\t// \t\t\t\t\ttoSummon,\r\n\t// \t\t\t\t\t1,\r\n\t// \t\t\t\t\tfriendlyBoard,\r\n\t// \t\t\t\t\tfriendlyHeroEntity,\r\n\t// \t\t\t\t\totherBoard,\r\n\t// \t\t\t\t\totherHeroEntity,\r\n\t// \t\t\t\t\tgameState,\r\n\t// \t\t\t\t\tfriendlyHeroEntity.friendly,\r\n\t// \t\t\t\t\tfalse,\r\n\t// \t\t\t\t),\r\n\t// \t\t\t);\r\n\t// \t\t}\r\n\t// \t}\r\n\t// }\r\n\tperformEntitySpawns(\r\n\t\tcandidateEntities,\r\n\t\tfriendlyBoard,\r\n\t\tfriendlyHeroEntity,\r\n\t\tsecretTriggered,\r\n\t\t0,\r\n\t\totherBoard,\r\n\t\totherHeroEntity,\r\n\t\tgameState,\r\n\t);\r\n};\r\n\r\nexport interface OnDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnAfterDeathInput {\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly deadEntities: BoardEntity[];\r\n\treadonly deadEntitiesIndexesFromRight: number[];\r\n\treadonly gameState: FullGameState;\r\n}\r\n\r\n/** A friendly board minion just died (during death processing). Implementations filter (e.g. Taunt) as needed. */\r\nexport interface OnAfterFriendlyMinionDeathInput {\r\n\treadonly deadEntity: BoardEntity;\r\n\treadonly board: BoardEntity[];\r\n\treadonly boardBeforeProcs: BoardEntity[];\r\n\treadonly hero: BgsPlayerEntity;\r\n\treadonly otherBoard: BoardEntity[];\r\n\treadonly otherHero: BgsPlayerEntity;\r\n\treadonly gameState: FullGameState;\r\n}\r\nexport interface OnMinionKilledInput {\r\n\treadonly killer: BoardEntity;\r\n\treadonly hadVenomous: boolean;\r\n\treadonly killerIsAttacking: boolean;\r\n\treadonly minionKilled: BoardEntity;\r\n\treadonly attackingHero: BgsPlayerEntity;\r\n\treadonly attackingBoard: BoardEntity[];\r\n\treadonly defendingHero: BgsPlayerEntity;\r\n\treadonly defendingBoard: BoardEntity[];\r\n\treadonly defenderNeighbours: readonly BoardEntity[];\r\n\treadonly gameState: FullGameState;\r\n\treadonly playerIsFriendly: boolean;\r\n}\r\n"]}
@@ -3,4 +3,4 @@ import { BoardEntity } from '../../board-entity';
3
3
  import { BoardSecret } from '../../board-secret';
4
4
  import { StartOfCombatTiming } from '../../cards/card.interface';
5
5
  import { SoCInput } from './start-of-combat-input';
6
- export declare const performStartOfCombatAction: (cardId: string, entity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret, input: SoCInput, processDeaths: boolean, timing?: StartOfCombatTiming, doSummonsWhenSpace?: boolean) => boolean;
6
+ export declare const performStartOfCombatAction: (cardId: string, entity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret, input: SoCInput, processDeaths: boolean, timing?: StartOfCombatTiming) => boolean;
@@ -61,7 +61,7 @@ const training_certificate_1 = require("../../cards/impl/trinket/training-certif
61
61
  const valorous_medaillion_1 = require("../../cards/impl/trinket/valorous-medaillion");
62
62
  const attack_1 = require("../attack");
63
63
  const summon_when_space_1 = require("../summon-when-space");
64
- const performStartOfCombatAction = (cardId, entity, input, processDeaths, timing, doSummonsWhenSpace = true) => {
64
+ const performStartOfCombatAction = (cardId, entity, input, processDeaths, timing) => {
65
65
  let hasTriggered = false;
66
66
  const promoPortraitCount = getPromoPortraitCount(input.playerEntity);
67
67
  for (let i = promoPortraitCount; i >= 0; i--) {
@@ -76,8 +76,10 @@ const performStartOfCombatAction = (cardId, entity, input, processDeaths, timing
76
76
  if (!!hasTriggered) {
77
77
  if (processDeaths) {
78
78
  (0, attack_1.processMinionDeath)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState, true);
79
- if (doSummonsWhenSpace) {
80
- const shouldRecomputeCurrentAttacker = (0, summon_when_space_1.handleSummonsWhenSpace)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState);
79
+ if (!!hasTriggered) {
80
+ const shouldRecomputeCurrentAttacker = typeof hasTriggered === 'object' && hasTriggered.skipSummonsWhenSpace
81
+ ? false
82
+ : (0, summon_when_space_1.handleSummonsWhenSpace)(input.playerBoard, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState);
81
83
  if (typeof hasTriggered === 'boolean') {
82
84
  hasTriggered = hasTriggered || shouldRecomputeCurrentAttacker;
83
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"soc-action-processor.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/soc-action-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\nimport { hasStartOfCombat, StartOfCombatCard, StartOfCombatTiming } from '../../cards/card.interface';\r\nimport { cardMappings } from '../../cards/impl/_card-mappings';\r\nimport { AnomalousTwin } from '../../cards/impl/anomaly/anomalous-twin';\r\nimport { BlessedOrBlighted } from '../../cards/impl/anomaly/blessed-or-blighted';\r\nimport { BoonOfBeetles } from '../../cards/impl/bg-spell/boon-of-beetles';\r\nimport { ToxicTumbleweed } from '../../cards/impl/bg-spell/toxic-tumbleweed';\r\nimport { UpperHand } from '../../cards/impl/bg-spell/upper-hand';\r\nimport { AimHigh } from '../../cards/impl/hero-power/aim-high';\r\nimport { AimLeft } from '../../cards/impl/hero-power/aim-left';\r\nimport { AimLow } from '../../cards/impl/hero-power/aim-low';\r\nimport { AimRight } from '../../cards/impl/hero-power/aim-right';\r\nimport { AllWillBurn } from '../../cards/impl/hero-power/all-will-burn';\r\nimport { AvatarOfNzoth } from '../../cards/impl/hero-power/avatar-of-nzoth';\r\nimport { DieInsects } from '../../cards/impl/hero-power/die-insects';\r\nimport { EarthInvocation } from '../../cards/impl/hero-power/earth-invocation';\r\nimport { EmbraceYourRage } from '../../cards/impl/hero-power/embrace-your-rage';\r\nimport { FireInvocation } from '../../cards/impl/hero-power/fire-invocation';\r\nimport { FireTheCannons } from '../../cards/impl/hero-power/fire-the-cannons';\r\nimport { LightningInvocation } from '../../cards/impl/hero-power/lightning-invocation';\r\nimport { MurlocKing } from '../../cards/impl/hero-power/murloc-king';\r\nimport { NefariousFire } from '../../cards/impl/hero-power/nefarious-fire';\r\nimport { RapidReanimation } from '../../cards/impl/hero-power/rapid-reanimation';\r\nimport { RebornRites } from '../../cards/impl/hero-power/reborn-rites';\r\nimport { Tentacular } from '../../cards/impl/hero-power/tentacular';\r\nimport { WaterInvocation } from '../../cards/impl/hero-power/water-invocation';\r\nimport { WaxWarband } from '../../cards/impl/hero-power/wax-warband';\r\nimport { AmberGuardian } from '../../cards/impl/minion/amber-guardian';\r\nimport { AudaciousAnchor } from '../../cards/impl/minion/audacious-anchor';\r\nimport { CarbonicCopy } from '../../cards/impl/minion/carbonic-copy';\r\nimport { CorruptedMyrmidon } from '../../cards/impl/minion/corrupted-myrmidon';\r\nimport { ElderTaggawag } from '../../cards/impl/minion/elder-taggawag';\r\nimport { HawkstriderHerald } from '../../cards/impl/minion/hawkstrider-herald';\r\nimport { MantidQueen } from '../../cards/impl/minion/mantid-queen';\r\nimport { Sandy } from '../../cards/impl/minion/sandy';\r\nimport { SunScreener } from '../../cards/impl/minion/sun-screener';\r\nimport { TheUninvitedGuest } from '../../cards/impl/minion/the-uninvited-guest';\r\nimport { ThousandthPaperDrake } from '../../cards/impl/minion/thousandth-paper-drake';\r\nimport { YulonFortuneGranter } from '../../cards/impl/minion/yulon-fortune-granter';\r\nimport { EvilTwin } from '../../cards/impl/quest-reward/evil-twin';\r\nimport { StaffOfOrigination } from '../../cards/impl/quest-reward/staff-of-origination';\r\nimport { StolenGold } from '../../cards/impl/quest-reward/stolen-gold';\r\nimport { FleetingVigor } from '../../cards/impl/spell/fleeting-vigor';\r\nimport { BronzeTimepiece } from '../../cards/impl/trinket/bronze-timepiece';\r\nimport { EmeraldDreamcatcher } from '../../cards/impl/trinket/emerald-dreamcatcher';\r\nimport { EternalPortrait } from '../../cards/impl/trinket/eternal-portrait';\r\nimport { FishySticker } from '../../cards/impl/trinket/fishy-sticker';\r\nimport { HoggyBank } from '../../cards/impl/trinket/hoggy-bank';\r\nimport { HollyMallet } from '../../cards/impl/trinket/holly-mallet';\r\nimport { IronforgeAnvil } from '../../cards/impl/trinket/ironforge-anvil';\r\nimport { JarredFrostling } from '../../cards/impl/trinket/jarred-frostling';\r\nimport { KarazhanChessSet } from '../../cards/impl/trinket/karazhan-chess-set';\r\nimport { RivendarePortrait } from '../../cards/impl/trinket/rivendare-portrait';\r\nimport { RustyTrident } from '../../cards/impl/trinket/rusty-trident';\r\nimport { ShipInABottle } from '../../cards/impl/trinket/ship-in-a-bottle';\r\nimport { SummoningSphere } from '../../cards/impl/trinket/summoning-sphere';\r\nimport { TinyfinOnesie } from '../../cards/impl/trinket/tinyfin-onesie';\r\nimport { TrainingCertificate } from '../../cards/impl/trinket/training-certificate';\r\nimport { ValorousMedallion } from '../../cards/impl/trinket/valorous-medaillion';\r\nimport { CardIds } from '../../services/card-ids';\r\nimport { processMinionDeath } from '../attack';\r\nimport { handleSummonsWhenSpace } from '../summon-when-space';\r\nimport { SoCInput } from './start-of-combat-input';\r\n\r\nexport const performStartOfCombatAction = (\r\n\tcardId: string,\r\n\tentity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\tinput: SoCInput,\r\n\tprocessDeaths: boolean,\r\n\ttiming?: StartOfCombatTiming,\r\n\tdoSummonsWhenSpace = true,\r\n): boolean => {\r\n\tlet hasTriggered:\r\n\t\t| boolean\r\n\t\t| {\r\n\t\t\t\thasTriggered: boolean;\r\n\t\t\t\tshouldRecomputeCurrentAttacker: boolean;\r\n\t\t } = false;\r\n\tconst promoPortraitCount = getPromoPortraitCount(input.playerEntity);\r\n\tfor (let i = promoPortraitCount; i >= 0; i--) {\r\n\t\tconst card = getStartOfCombatAction(cardId);\r\n\t\tif (!!timing && card?.startOfCombatTiming !== timing) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst action = card?.startOfCombat;\r\n\t\tif (!!action) {\r\n\t\t\thasTriggered = action(entity, input);\r\n\t\t\t// Always proc it (for promo portrait), and use the hasTriggered for finer control\r\n\t\t\tonStartOfCombatTriggered(i, cardId, input.playerEntity);\r\n\t\t\tif (!!hasTriggered) {\r\n\t\t\t\tif (processDeaths) {\r\n\t\t\t\t\tprocessMinionDeath(\r\n\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=2eacbbc2-7dfa-487b-951d-0fa6d31d175e&turn=25&action=1\r\n\t\t\t\t\t\t// It looks like it doesn't look for the \"summons when space\" between Stitched Salvager's SoC and\r\n\t\t\t\t\t\t// Hawkstrider Herald SoC\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t);\r\n\t\t\t\t\t// https://replays.firestoneapp.com/?reviewId=6293597f-28fa-472e-ba8c-35f6b7deef58&turn=31&action=6\r\n\t\t\t\t\t// The first RapidReanimation triggers, resummons the target, then the second RapidReanimation triggers\r\n\t\t\t\t\t// So we need to process the resummon as soon as the minion dies, and before processing the\r\n\t\t\t\t\t// second RapidReanimation\r\n\t\t\t\t\tif (doSummonsWhenSpace) {\r\n\t\t\t\t\t\tconst shouldRecomputeCurrentAttacker = handleSummonsWhenSpace(\r\n\t\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tif (typeof hasTriggered === 'boolean') {\r\n\t\t\t\t\t\t\thasTriggered = hasTriggered || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker =\r\n\t\t\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (typeof hasTriggered !== 'boolean' && hasTriggered.shouldRecomputeCurrentAttacker) {\r\n\t\t\t\t\tinput.currentAttacker =\r\n\t\t\t\t\t\tinput.playerBoard.length > input.opponentBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 0\r\n\t\t\t\t\t\t\t\t: 1\r\n\t\t\t\t\t\t\t: input.opponentBoard.length > input.playerBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 1\r\n\t\t\t\t\t\t\t\t: 0\r\n\t\t\t\t\t\t\t: Math.round(Math.random());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn !!hasTriggered;\r\n};\r\n\r\n// TODO: load all cards on start, then do some programmatic mapping\r\nconst startOfCombatActionById = new Map<string, StartOfCombatCard | null>();\r\n\r\nconst getStartOfCombatAction = (cardId: string): StartOfCombatCard => {\r\n\tconst hit = startOfCombatActionById.get(cardId);\r\n\tif (hit !== undefined) {\r\n\t\treturn hit;\r\n\t}\r\n\tconst resolved = lookupStartOfCombatAction(cardId);\r\n\tstartOfCombatActionById.set(cardId, resolved);\r\n\treturn resolved;\r\n};\r\n\r\nconst lookupStartOfCombatAction = (cardId: string): StartOfCombatCard => {\r\n\tswitch (cardId) {\r\n\t\t// Quest rewards\r\n\t\tcase CardIds.EvilTwin:\r\n\t\t\treturn EvilTwin;\r\n\t\tcase CardIds.StaffOfOrigination_BG24_Reward_312:\r\n\t\t\treturn StaffOfOrigination;\r\n\t\tcase CardIds.StolenGold:\r\n\t\t\treturn StolenGold;\r\n\r\n\t\t// Trinkets\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\t\treturn HollyMallet;\r\n\t\tcase CardIds.TrainingCertificate_BG30_MagicItem_962:\r\n\t\t\treturn TrainingCertificate;\r\n\t\tcase CardIds.ValorousMedallion_BG30_MagicItem_970:\r\n\t\tcase CardIds.ValorousMedallion_ValorousMedallionToken_BG30_MagicItem_970t:\r\n\t\t\treturn ValorousMedallion;\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\t\treturn EmeraldDreamcatcher;\r\n\t\tcase CardIds.JarredFrostling_BG30_MagicItem_952:\r\n\t\t\treturn JarredFrostling;\r\n\t\tcase CardIds.RustyTrident_BG30_MagicItem_917:\r\n\t\t\treturn RustyTrident;\r\n\t\tcase CardIds.HoggyBank_BG30_MagicItem_411:\r\n\t\t\treturn HoggyBank;\r\n\t\tcase CardIds.ShipInABottle_BG30_MagicItem_407:\r\n\t\t\treturn ShipInABottle;\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\t\treturn EternalPortrait;\r\n\t\tcase CardIds.RivendarePortrait_BG30_MagicItem_310:\r\n\t\t\treturn RivendarePortrait;\r\n\t\tcase CardIds.TinyfinOnesie_BG30_MagicItem_441:\r\n\t\t\treturn TinyfinOnesie;\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\t\treturn BronzeTimepiece;\r\n\t\tcase CardIds.IronforgeAnvil_BG30_MagicItem_403:\r\n\t\t\treturn IronforgeAnvil;\r\n\t\tcase CardIds.KarazhanChessSet_BG30_MagicItem_972:\r\n\t\t\treturn KarazhanChessSet;\r\n\t\t// case CardIds.FishySticker_BG30_MagicItem_821:\r\n\t\tcase CardIds.FishySticker_FishyStickerToken_BG30_MagicItem_821t2:\r\n\t\t\treturn FishySticker;\r\n\t\tcase CardIds.SummoningSphere_BGDUO_MagicItem_003:\r\n\t\t\treturn SummoningSphere;\r\n\r\n\t\t// Hero powers\r\n\t\tcase CardIds.EarthInvocationToken:\r\n\t\t\treturn EarthInvocation;\r\n\t\tcase CardIds.WaterInvocationToken:\r\n\t\t\treturn WaterInvocation;\r\n\t\tcase CardIds.FireInvocationToken:\r\n\t\t\treturn FireInvocation;\r\n\t\tcase CardIds.LightningInvocationToken:\r\n\t\t\treturn LightningInvocation;\r\n\t\tcase CardIds.AllWillBurn:\r\n\t\t\treturn AllWillBurn;\r\n\t\tcase CardIds.AvatarOfNzoth:\r\n\t\t\treturn AvatarOfNzoth;\r\n\t\tcase CardIds.EmbraceYourRage:\r\n\t\t\treturn EmbraceYourRage;\r\n\t\tcase CardIds.Ozumat_Tentacular:\r\n\t\t\treturn Tentacular;\r\n\t\tcase CardIds.RebornRites:\r\n\t\t\treturn RebornRites;\r\n\t\tcase CardIds.TeronGorefiend_RapidReanimation:\r\n\t\t\treturn RapidReanimation;\r\n\t\tcase CardIds.WaxWarband:\r\n\t\t\treturn WaxWarband;\r\n\t\tcase CardIds.DieInsects_TB_BaconShop_HP_019:\r\n\t\t\treturn DieInsects;\r\n\t\tcase CardIds.FireTheCannons:\r\n\t\t\treturn FireTheCannons;\r\n\t\tcase CardIds.NefariousFire:\r\n\t\t\treturn NefariousFire;\r\n\t\tcase CardIds.MurlocKing:\r\n\t\t\treturn MurlocKing;\r\n\t\tcase CardIds.AimLeftToken:\r\n\t\t\treturn AimLeft;\r\n\t\tcase CardIds.AimRightToken:\r\n\t\t\treturn AimRight;\r\n\t\tcase CardIds.AimLowToken:\r\n\t\t\treturn AimLow;\r\n\t\tcase CardIds.AimHighToken:\r\n\t\t\treturn AimHigh;\r\n\r\n\t\t// Anomalies\r\n\t\tcase CardIds.BlessedOrBlighted_BG27_Anomaly_726:\r\n\t\t\treturn BlessedOrBlighted;\r\n\t\tcase CardIds.AnomalousTwin_BG27_Anomaly_560:\r\n\t\t\treturn AnomalousTwin;\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn BoonOfBeetles;\r\n\r\n\t\t// Spells\r\n\t\tcase CardIds.ToxicTumbleweed_BG28_641:\r\n\t\t\treturn ToxicTumbleweed;\r\n\t\tcase CardIds.UpperHand_BG28_573:\r\n\t\t\treturn UpperHand;\r\n\t\tcase CardIds.FleetingVigor_BG28_519:\r\n\t\t\treturn FleetingVigor;\r\n\r\n\t\t// Minions\r\n\t\tcase CardIds.AmberGuardian_BG24_500:\r\n\t\tcase CardIds.AmberGuardian_BG24_500_G:\r\n\t\t\treturn AmberGuardian;\r\n\t\t// case CardIds.SanctumRester_BG26_356:\r\n\t\t// case CardIds.SanctumRester_BG26_356_G:\r\n\t\t// \treturn SanctumRester;\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012:\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012_G:\r\n\t\t\treturn CorruptedMyrmidon;\r\n\t\tcase CardIds.MantidQueen_BG22_402:\r\n\t\tcase CardIds.MantidQueen_BG22_402_G:\r\n\t\t\treturn MantidQueen;\r\n\t\tcase CardIds.CarbonicCopy_BG27_503:\r\n\t\tcase CardIds.CarbonicCopy_BG27_503_G:\r\n\t\t\treturn CarbonicCopy;\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079:\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079_G:\r\n\t\t\treturn HawkstriderHerald;\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904:\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904_G:\r\n\t\t\treturn AudaciousAnchor;\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810:\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810_G:\r\n\t\t\treturn ThousandthPaperDrake;\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811:\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811_G:\r\n\t\t\treturn YulonFortuneGranter;\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872:\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872_G:\r\n\t\t// \treturn HoardingHatespawn;\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875:\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875_G:\r\n\t\t\treturn TheUninvitedGuest;\r\n\t\tcase CardIds.Sandy_BGDUO_125:\r\n\t\tcase CardIds.Sandy_BGDUO_125_G:\r\n\t\t\treturn Sandy;\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy:\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy_G:\r\n\t\t\treturn ElderTaggawag;\r\n\t\tcase CardIds.SunScreener_BG30_101:\r\n\t\tcase CardIds.SunScreener_BG30_101_G:\r\n\t\t\treturn SunScreener;\r\n\r\n\t\tdefault:\r\n\t\t\tconst candidate = cardMappings[cardId];\r\n\t\t\tif (hasStartOfCombat(candidate)) {\r\n\t\t\t\treturn candidate;\r\n\t\t\t}\r\n\t\t\treturn null;\r\n\t}\r\n};\r\n\r\nconst onStartOfCombatTriggered = (iteration: number, triggeredCardId: string, playerEntity: BgsPlayerEntity) => {\r\n\t// Some procs are iso-functional, and don't update the promo portrait\r\n\tconst promoPortraits = playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t);\r\n\tif (promoPortraits.length === 0 || iteration === 0 || iteration > promoPortraits.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tswitch (triggeredCardId) {\r\n\t\tcase CardIds.StolenGold:\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\tcase CardIds.SwattingInsects:\r\n\t\tcase CardIds.RebornRites:\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn;\r\n\t}\r\n\r\n\tconst promoPortrait = promoPortraits[iteration - 1];\r\n\tpromoPortrait.scriptDataNum1--;\r\n};\r\n\r\nconst getPromoPortraitCount = (playerEntity: BgsPlayerEntity) => {\r\n\treturn playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t).length;\r\n};\r\n"]}
1
+ {"version":3,"file":"soc-action-processor.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/soc-action-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\nimport { hasStartOfCombat, StartOfCombatCard, StartOfCombatTiming } from '../../cards/card.interface';\r\nimport { cardMappings } from '../../cards/impl/_card-mappings';\r\nimport { AnomalousTwin } from '../../cards/impl/anomaly/anomalous-twin';\r\nimport { BlessedOrBlighted } from '../../cards/impl/anomaly/blessed-or-blighted';\r\nimport { BoonOfBeetles } from '../../cards/impl/bg-spell/boon-of-beetles';\r\nimport { ToxicTumbleweed } from '../../cards/impl/bg-spell/toxic-tumbleweed';\r\nimport { UpperHand } from '../../cards/impl/bg-spell/upper-hand';\r\nimport { AimHigh } from '../../cards/impl/hero-power/aim-high';\r\nimport { AimLeft } from '../../cards/impl/hero-power/aim-left';\r\nimport { AimLow } from '../../cards/impl/hero-power/aim-low';\r\nimport { AimRight } from '../../cards/impl/hero-power/aim-right';\r\nimport { AllWillBurn } from '../../cards/impl/hero-power/all-will-burn';\r\nimport { AvatarOfNzoth } from '../../cards/impl/hero-power/avatar-of-nzoth';\r\nimport { DieInsects } from '../../cards/impl/hero-power/die-insects';\r\nimport { EarthInvocation } from '../../cards/impl/hero-power/earth-invocation';\r\nimport { EmbraceYourRage } from '../../cards/impl/hero-power/embrace-your-rage';\r\nimport { FireInvocation } from '../../cards/impl/hero-power/fire-invocation';\r\nimport { FireTheCannons } from '../../cards/impl/hero-power/fire-the-cannons';\r\nimport { LightningInvocation } from '../../cards/impl/hero-power/lightning-invocation';\r\nimport { MurlocKing } from '../../cards/impl/hero-power/murloc-king';\r\nimport { NefariousFire } from '../../cards/impl/hero-power/nefarious-fire';\r\nimport { RapidReanimation } from '../../cards/impl/hero-power/rapid-reanimation';\r\nimport { RebornRites } from '../../cards/impl/hero-power/reborn-rites';\r\nimport { Tentacular } from '../../cards/impl/hero-power/tentacular';\r\nimport { WaterInvocation } from '../../cards/impl/hero-power/water-invocation';\r\nimport { WaxWarband } from '../../cards/impl/hero-power/wax-warband';\r\nimport { AmberGuardian } from '../../cards/impl/minion/amber-guardian';\r\nimport { AudaciousAnchor } from '../../cards/impl/minion/audacious-anchor';\r\nimport { CarbonicCopy } from '../../cards/impl/minion/carbonic-copy';\r\nimport { CorruptedMyrmidon } from '../../cards/impl/minion/corrupted-myrmidon';\r\nimport { ElderTaggawag } from '../../cards/impl/minion/elder-taggawag';\r\nimport { HawkstriderHerald } from '../../cards/impl/minion/hawkstrider-herald';\r\nimport { MantidQueen } from '../../cards/impl/minion/mantid-queen';\r\nimport { Sandy } from '../../cards/impl/minion/sandy';\r\nimport { SunScreener } from '../../cards/impl/minion/sun-screener';\r\nimport { TheUninvitedGuest } from '../../cards/impl/minion/the-uninvited-guest';\r\nimport { ThousandthPaperDrake } from '../../cards/impl/minion/thousandth-paper-drake';\r\nimport { YulonFortuneGranter } from '../../cards/impl/minion/yulon-fortune-granter';\r\nimport { EvilTwin } from '../../cards/impl/quest-reward/evil-twin';\r\nimport { StaffOfOrigination } from '../../cards/impl/quest-reward/staff-of-origination';\r\nimport { StolenGold } from '../../cards/impl/quest-reward/stolen-gold';\r\nimport { FleetingVigor } from '../../cards/impl/spell/fleeting-vigor';\r\nimport { BronzeTimepiece } from '../../cards/impl/trinket/bronze-timepiece';\r\nimport { EmeraldDreamcatcher } from '../../cards/impl/trinket/emerald-dreamcatcher';\r\nimport { EternalPortrait } from '../../cards/impl/trinket/eternal-portrait';\r\nimport { FishySticker } from '../../cards/impl/trinket/fishy-sticker';\r\nimport { HoggyBank } from '../../cards/impl/trinket/hoggy-bank';\r\nimport { HollyMallet } from '../../cards/impl/trinket/holly-mallet';\r\nimport { IronforgeAnvil } from '../../cards/impl/trinket/ironforge-anvil';\r\nimport { JarredFrostling } from '../../cards/impl/trinket/jarred-frostling';\r\nimport { KarazhanChessSet } from '../../cards/impl/trinket/karazhan-chess-set';\r\nimport { RivendarePortrait } from '../../cards/impl/trinket/rivendare-portrait';\r\nimport { RustyTrident } from '../../cards/impl/trinket/rusty-trident';\r\nimport { ShipInABottle } from '../../cards/impl/trinket/ship-in-a-bottle';\r\nimport { SummoningSphere } from '../../cards/impl/trinket/summoning-sphere';\r\nimport { TinyfinOnesie } from '../../cards/impl/trinket/tinyfin-onesie';\r\nimport { TrainingCertificate } from '../../cards/impl/trinket/training-certificate';\r\nimport { ValorousMedallion } from '../../cards/impl/trinket/valorous-medaillion';\r\nimport { CardIds } from '../../services/card-ids';\r\nimport { processMinionDeath } from '../attack';\r\nimport { handleSummonsWhenSpace } from '../summon-when-space';\r\nimport { SoCInput } from './start-of-combat-input';\r\n\r\nexport const performStartOfCombatAction = (\r\n\tcardId: string,\r\n\tentity: BoardEntity | BoardTrinket | BgsPlayerEntity | BoardSecret,\r\n\tinput: SoCInput,\r\n\tprocessDeaths: boolean,\r\n\ttiming?: StartOfCombatTiming,\r\n): boolean => {\r\n\tlet hasTriggered:\r\n\t\t| boolean\r\n\t\t| {\r\n\t\t\t\thasTriggered: boolean;\r\n\t\t\t\tshouldRecomputeCurrentAttacker: boolean;\r\n\t\t\t\tskipSummonsWhenSpace?: boolean;\r\n\t\t } = false;\r\n\tconst promoPortraitCount = getPromoPortraitCount(input.playerEntity);\r\n\tfor (let i = promoPortraitCount; i >= 0; i--) {\r\n\t\tconst card = getStartOfCombatAction(cardId);\r\n\t\tif (!!timing && card?.startOfCombatTiming !== timing) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tconst action = card?.startOfCombat;\r\n\t\tif (!!action) {\r\n\t\t\thasTriggered = action(entity, input);\r\n\t\t\t// Always proc it (for promo portrait), and use the hasTriggered for finer control\r\n\t\t\tonStartOfCombatTriggered(i, cardId, input.playerEntity);\r\n\t\t\tif (!!hasTriggered) {\r\n\t\t\t\tif (processDeaths) {\r\n\t\t\t\t\tprocessMinionDeath(\r\n\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=2eacbbc2-7dfa-487b-951d-0fa6d31d175e&turn=25&action=1\r\n\t\t\t\t\t\t// It looks like it doesn't look for the \"summons when space\" between Stitched Salvager's SoC and\r\n\t\t\t\t\t\t// Hawkstrider Herald SoC\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t);\r\n\t\t\t\t\t// https://replays.firestoneapp.com/?reviewId=6293597f-28fa-472e-ba8c-35f6b7deef58&turn=31&action=6\r\n\t\t\t\t\t// The first RapidReanimation triggers, resummons the target, then the second RapidReanimation triggers\r\n\t\t\t\t\t// So we need to process the resummon as soon as the minion dies, and before processing the\r\n\t\t\t\t\t// second RapidReanimation\r\n\t\t\t\t\tif (!!hasTriggered) {\r\n\t\t\t\t\t\tconst shouldRecomputeCurrentAttacker =\r\n\t\t\t\t\t\t\ttypeof hasTriggered === 'object' && hasTriggered.skipSummonsWhenSpace\r\n\t\t\t\t\t\t\t\t? false\r\n\t\t\t\t\t\t\t\t: handleSummonsWhenSpace(\r\n\t\t\t\t\t\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\t\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t\t\t\t );\r\n\t\t\t\t\t\tif (typeof hasTriggered === 'boolean') {\r\n\t\t\t\t\t\t\thasTriggered = hasTriggered || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker =\r\n\t\t\t\t\t\t\t\thasTriggered.shouldRecomputeCurrentAttacker || shouldRecomputeCurrentAttacker;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (typeof hasTriggered !== 'boolean' && hasTriggered.shouldRecomputeCurrentAttacker) {\r\n\t\t\t\t\tinput.currentAttacker =\r\n\t\t\t\t\t\tinput.playerBoard.length > input.opponentBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 0\r\n\t\t\t\t\t\t\t\t: 1\r\n\t\t\t\t\t\t\t: input.opponentBoard.length > input.playerBoard.length\r\n\t\t\t\t\t\t\t? input.playerIsFriendly\r\n\t\t\t\t\t\t\t\t? 1\r\n\t\t\t\t\t\t\t\t: 0\r\n\t\t\t\t\t\t\t: Math.round(Math.random());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn !!hasTriggered;\r\n};\r\n\r\n// TODO: load all cards on start, then do some programmatic mapping\r\nconst startOfCombatActionById = new Map<string, StartOfCombatCard | null>();\r\n\r\nconst getStartOfCombatAction = (cardId: string): StartOfCombatCard => {\r\n\tconst hit = startOfCombatActionById.get(cardId);\r\n\tif (hit !== undefined) {\r\n\t\treturn hit;\r\n\t}\r\n\tconst resolved = lookupStartOfCombatAction(cardId);\r\n\tstartOfCombatActionById.set(cardId, resolved);\r\n\treturn resolved;\r\n};\r\n\r\nconst lookupStartOfCombatAction = (cardId: string): StartOfCombatCard => {\r\n\tswitch (cardId) {\r\n\t\t// Quest rewards\r\n\t\tcase CardIds.EvilTwin:\r\n\t\t\treturn EvilTwin;\r\n\t\tcase CardIds.StaffOfOrigination_BG24_Reward_312:\r\n\t\t\treturn StaffOfOrigination;\r\n\t\tcase CardIds.StolenGold:\r\n\t\t\treturn StolenGold;\r\n\r\n\t\t// Trinkets\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\t\treturn HollyMallet;\r\n\t\tcase CardIds.TrainingCertificate_BG30_MagicItem_962:\r\n\t\t\treturn TrainingCertificate;\r\n\t\tcase CardIds.ValorousMedallion_BG30_MagicItem_970:\r\n\t\tcase CardIds.ValorousMedallion_ValorousMedallionToken_BG30_MagicItem_970t:\r\n\t\t\treturn ValorousMedallion;\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\t\treturn EmeraldDreamcatcher;\r\n\t\tcase CardIds.JarredFrostling_BG30_MagicItem_952:\r\n\t\t\treturn JarredFrostling;\r\n\t\tcase CardIds.RustyTrident_BG30_MagicItem_917:\r\n\t\t\treturn RustyTrident;\r\n\t\tcase CardIds.HoggyBank_BG30_MagicItem_411:\r\n\t\t\treturn HoggyBank;\r\n\t\tcase CardIds.ShipInABottle_BG30_MagicItem_407:\r\n\t\t\treturn ShipInABottle;\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\t\treturn EternalPortrait;\r\n\t\tcase CardIds.RivendarePortrait_BG30_MagicItem_310:\r\n\t\t\treturn RivendarePortrait;\r\n\t\tcase CardIds.TinyfinOnesie_BG30_MagicItem_441:\r\n\t\t\treturn TinyfinOnesie;\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\t\treturn BronzeTimepiece;\r\n\t\tcase CardIds.IronforgeAnvil_BG30_MagicItem_403:\r\n\t\t\treturn IronforgeAnvil;\r\n\t\tcase CardIds.KarazhanChessSet_BG30_MagicItem_972:\r\n\t\t\treturn KarazhanChessSet;\r\n\t\t// case CardIds.FishySticker_BG30_MagicItem_821:\r\n\t\tcase CardIds.FishySticker_FishyStickerToken_BG30_MagicItem_821t2:\r\n\t\t\treturn FishySticker;\r\n\t\tcase CardIds.SummoningSphere_BGDUO_MagicItem_003:\r\n\t\t\treturn SummoningSphere;\r\n\r\n\t\t// Hero powers\r\n\t\tcase CardIds.EarthInvocationToken:\r\n\t\t\treturn EarthInvocation;\r\n\t\tcase CardIds.WaterInvocationToken:\r\n\t\t\treturn WaterInvocation;\r\n\t\tcase CardIds.FireInvocationToken:\r\n\t\t\treturn FireInvocation;\r\n\t\tcase CardIds.LightningInvocationToken:\r\n\t\t\treturn LightningInvocation;\r\n\t\tcase CardIds.AllWillBurn:\r\n\t\t\treturn AllWillBurn;\r\n\t\tcase CardIds.AvatarOfNzoth:\r\n\t\t\treturn AvatarOfNzoth;\r\n\t\tcase CardIds.EmbraceYourRage:\r\n\t\t\treturn EmbraceYourRage;\r\n\t\tcase CardIds.Ozumat_Tentacular:\r\n\t\t\treturn Tentacular;\r\n\t\tcase CardIds.RebornRites:\r\n\t\t\treturn RebornRites;\r\n\t\tcase CardIds.TeronGorefiend_RapidReanimation:\r\n\t\t\treturn RapidReanimation;\r\n\t\tcase CardIds.WaxWarband:\r\n\t\t\treturn WaxWarband;\r\n\t\tcase CardIds.DieInsects_TB_BaconShop_HP_019:\r\n\t\t\treturn DieInsects;\r\n\t\tcase CardIds.FireTheCannons:\r\n\t\t\treturn FireTheCannons;\r\n\t\tcase CardIds.NefariousFire:\r\n\t\t\treturn NefariousFire;\r\n\t\tcase CardIds.MurlocKing:\r\n\t\t\treturn MurlocKing;\r\n\t\tcase CardIds.AimLeftToken:\r\n\t\t\treturn AimLeft;\r\n\t\tcase CardIds.AimRightToken:\r\n\t\t\treturn AimRight;\r\n\t\tcase CardIds.AimLowToken:\r\n\t\t\treturn AimLow;\r\n\t\tcase CardIds.AimHighToken:\r\n\t\t\treturn AimHigh;\r\n\r\n\t\t// Anomalies\r\n\t\tcase CardIds.BlessedOrBlighted_BG27_Anomaly_726:\r\n\t\t\treturn BlessedOrBlighted;\r\n\t\tcase CardIds.AnomalousTwin_BG27_Anomaly_560:\r\n\t\t\treturn AnomalousTwin;\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn BoonOfBeetles;\r\n\r\n\t\t// Spells\r\n\t\tcase CardIds.ToxicTumbleweed_BG28_641:\r\n\t\t\treturn ToxicTumbleweed;\r\n\t\tcase CardIds.UpperHand_BG28_573:\r\n\t\t\treturn UpperHand;\r\n\t\tcase CardIds.FleetingVigor_BG28_519:\r\n\t\t\treturn FleetingVigor;\r\n\r\n\t\t// Minions\r\n\t\tcase CardIds.AmberGuardian_BG24_500:\r\n\t\tcase CardIds.AmberGuardian_BG24_500_G:\r\n\t\t\treturn AmberGuardian;\r\n\t\t// case CardIds.SanctumRester_BG26_356:\r\n\t\t// case CardIds.SanctumRester_BG26_356_G:\r\n\t\t// \treturn SanctumRester;\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012:\r\n\t\tcase CardIds.CorruptedMyrmidon_BG23_012_G:\r\n\t\t\treturn CorruptedMyrmidon;\r\n\t\tcase CardIds.MantidQueen_BG22_402:\r\n\t\tcase CardIds.MantidQueen_BG22_402_G:\r\n\t\t\treturn MantidQueen;\r\n\t\tcase CardIds.CarbonicCopy_BG27_503:\r\n\t\tcase CardIds.CarbonicCopy_BG27_503_G:\r\n\t\t\treturn CarbonicCopy;\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079:\r\n\t\tcase CardIds.HawkstriderHerald_BG27_079_G:\r\n\t\t\treturn HawkstriderHerald;\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904:\r\n\t\tcase CardIds.AudaciousAnchor_BG28_904_G:\r\n\t\t\treturn AudaciousAnchor;\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810:\r\n\t\tcase CardIds.ThousandthPaperDrake_BG29_810_G:\r\n\t\t\treturn ThousandthPaperDrake;\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811:\r\n\t\tcase CardIds.YulonFortuneGranter_BG29_811_G:\r\n\t\t\treturn YulonFortuneGranter;\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872:\r\n\t\t// case CardIds.HoardingHatespawn_BG29_872_G:\r\n\t\t// \treturn HoardingHatespawn;\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875:\r\n\t\tcase CardIds.TheUninvitedGuest_BG29_875_G:\r\n\t\t\treturn TheUninvitedGuest;\r\n\t\tcase CardIds.Sandy_BGDUO_125:\r\n\t\tcase CardIds.Sandy_BGDUO_125_G:\r\n\t\t\treturn Sandy;\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy:\r\n\t\tcase CardIds.ElderTaggawag_TB_BaconShop_HERO_14_Buddy_G:\r\n\t\t\treturn ElderTaggawag;\r\n\t\tcase CardIds.SunScreener_BG30_101:\r\n\t\tcase CardIds.SunScreener_BG30_101_G:\r\n\t\t\treturn SunScreener;\r\n\r\n\t\tdefault:\r\n\t\t\tconst candidate = cardMappings[cardId];\r\n\t\t\tif (hasStartOfCombat(candidate)) {\r\n\t\t\t\treturn candidate;\r\n\t\t\t}\r\n\t\t\treturn null;\r\n\t}\r\n};\r\n\r\nconst onStartOfCombatTriggered = (iteration: number, triggeredCardId: string, playerEntity: BgsPlayerEntity) => {\r\n\t// Some procs are iso-functional, and don't update the promo portrait\r\n\tconst promoPortraits = playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t);\r\n\tif (promoPortraits.length === 0 || iteration === 0 || iteration > promoPortraits.length) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tswitch (triggeredCardId) {\r\n\t\tcase CardIds.StolenGold:\r\n\t\tcase CardIds.HolyMallet_BG30_MagicItem_902:\r\n\t\tcase CardIds.EmeraldDreamcatcher_BG30_MagicItem_542:\r\n\t\tcase CardIds.EternalPortrait_BG30_MagicItem_301:\r\n\t\tcase CardIds.BronzeTimepiece_BG30_MagicItem_995:\r\n\t\tcase CardIds.SwattingInsects:\r\n\t\tcase CardIds.RebornRites:\r\n\t\tcase CardIds.BoonOfBeetles_BG28_603:\r\n\t\t\treturn;\r\n\t}\r\n\r\n\tconst promoPortrait = promoPortraits[iteration - 1];\r\n\tpromoPortrait.scriptDataNum1--;\r\n};\r\n\r\nconst getPromoPortraitCount = (playerEntity: BgsPlayerEntity) => {\r\n\treturn playerEntity.trinkets.filter(\r\n\t\t(t) => t.cardId === CardIds.PromoPortrait_BG30_MagicItem_918 && t.scriptDataNum1 > 0,\r\n\t).length;\r\n};\r\n"]}
@@ -77,10 +77,10 @@ const performStartOfCombatMinionsForPlayer = (minion, input) => {
77
77
  if (input.playerEntity.startOfCombatDone) {
78
78
  return false;
79
79
  }
80
- hasProcessed = (0, soc_action_processor_1.performStartOfCombatAction)(minion.cardId, minion, input, true, undefined, false) || hasProcessed;
80
+ hasProcessed = (0, soc_action_processor_1.performStartOfCombatAction)(minion.cardId, minion, input, true, undefined) || hasProcessed;
81
81
  for (const enchantment of (_b = minion.enchantments) !== null && _b !== void 0 ? _b : []) {
82
82
  hasProcessed =
83
- (0, soc_action_processor_1.performStartOfCombatAction)(enchantment.cardId, minion, input, true, undefined, false) || hasProcessed;
83
+ (0, soc_action_processor_1.performStartOfCombatAction)(enchantment.cardId, minion, input, true, undefined) || hasProcessed;
84
84
  }
85
85
  }
86
86
  return hasProcessed;
@@ -1 +1 @@
1
- {"version":3,"file":"soc-minion.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/soc-minion.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { hasStartOfCombatFromHand } from '../../cards/card.interface';\r\nimport { cardMappings } from '../../cards/impl/_card-mappings';\r\nimport { CardIds } from '../../services/card-ids';\r\nimport { FullGameState } from '../internal-game-state';\r\nimport { performStartOfCombatAction } from './soc-action-processor';\r\nimport { SoCInput } from './start-of-combat-input';\r\n\r\nexport const 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\tgameState: FullGameState,\r\n): number => {\r\n\tlet attackerForStart = Math.random() < 0.5 ? 0 : 1;\r\n\tconst playerAttackers = [\r\n\t\t// Hand triggers first\r\n\t\t...playerEntity.hand.filter((e) => hasStartOfCombatFromHand(cardMappings[e.cardId])),\r\n\t\t...playerBoard,\r\n\t];\r\n\tconst opponentAttackers = [\r\n\t\t...opponentEntity.hand.filter((e) => hasStartOfCombatFromHand(cardMappings[e.cardId])),\r\n\t\t...opponentBoard,\r\n\t];\r\n\r\n\t// UPDATE 2025-11-16 We probably want to run the Start of Combat first for one player completely, then for the other\r\n\t// I thought it would alternate, but this apparently isn't the case:\r\n\t// https://replays.firestoneapp.com/?reviewId=af9053ee-9ee6-440a-a09f-b7fb2f4b7a3e&turn=9&action=0\r\n\twhile (playerAttackers.length > 0 || opponentAttackers.length > 0) {\r\n\t\tlet shouldUpdateNextPlayer = false;\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\tconst input = {\r\n\t\t\t\tplayerBoard: playerBoard,\r\n\t\t\t\tplayerEntity: playerEntity,\r\n\t\t\t\topponentBoard: opponentBoard,\r\n\t\t\t\topponentEntity: opponentEntity,\r\n\t\t\t\tplayerBoardBefore: playerBoardBefore,\r\n\t\t\t\topponentBoardBefore: opponentBoardBefore,\r\n\t\t\t\tplayerIsFriendly: true,\r\n\t\t\t\tcurrentAttacker: currentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t};\r\n\t\t\tconst newShouldUpdateNextPlayer = performStartOfCombatMinionsForPlayer(attacker, input);\r\n\t\t\tcurrentAttacker = input.currentAttacker;\r\n\t\t} else if (attackerForStart === 0 && playerAttackers.length === 0) {\r\n\t\t\tshouldUpdateNextPlayer = true;\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\tconst input = {\r\n\t\t\t\tplayerBoard: opponentBoard,\r\n\t\t\t\tplayerEntity: opponentEntity,\r\n\t\t\t\topponentBoard: playerBoard,\r\n\t\t\t\topponentEntity: playerEntity,\r\n\t\t\t\tplayerBoardBefore: opponentBoardBefore,\r\n\t\t\t\topponentBoardBefore: playerBoardBefore,\r\n\t\t\t\tplayerIsFriendly: false,\r\n\t\t\t\tcurrentAttacker: currentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t};\r\n\t\t\tconst newShouldUpdateNextPlayer = performStartOfCombatMinionsForPlayer(attacker, input);\r\n\t\t\tcurrentAttacker = input.currentAttacker;\r\n\t\t} else if (attackerForStart === 1 && opponentAttackers.length === 0) {\r\n\t\t\tshouldUpdateNextPlayer = true;\r\n\t\t}\r\n\r\n\t\tif (shouldUpdateNextPlayer) {\r\n\t\t\tattackerForStart = (attackerForStart + 1) % 2;\r\n\t\t}\r\n\t}\r\n\t// 2026-09-29: I'm having doubts as to whether the \"summonsWhenSpace\" should be called here.\r\n\t// https://replays.firestoneapp.com/?reviewId=71184008-9884-47d0-89fc-c175c37a3be3&turn=15&action=1\r\n\t// Bomm-in-a-Box triggers, then the player attacks, and only the does Tentacular procs\r\n\t// https://replays.firestoneapp.com/?reviewId=49582580-dae9-4079-b2ff-741bab446da6&turn=27&action=2\r\n\t// On this board, Heroic Broodmother attacks twice as part of the Start of Combat, then the\r\n\t// opponent's turn starts and it attacks immediately before giving Frostwolf Fervor a chance to proc\r\n\t// For now I will comment this out, and we'll see how that goes\r\n\t// const shouldRecomputeCurrentAttacker = handleSummonsWhenSpace(\r\n\t// \tplayerBoard,\r\n\t// \tplayerEntity,\r\n\t// \topponentBoard,\r\n\t// \topponentEntity,\r\n\t// \tgameState,\r\n\t// );\r\n\t// if (shouldRecomputeCurrentAttacker) {\r\n\t// \tcurrentAttacker =\r\n\t// \t\tplayerBoard.length > opponentBoard.length\r\n\t// \t\t\t? 0\r\n\t// \t\t\t: opponentBoard.length > playerBoard.length\r\n\t// \t\t\t? 1\r\n\t// \t\t\t: Math.round(Math.random());\r\n\t// }\r\n\treturn currentAttacker;\r\n};\r\n\r\n// Apparently, the board composition used for start of combat minion effects (like Red Whelp, and I assume it works the\r\n// 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// 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// Tamsin's Phylactery.\r\nexport const performStartOfCombatMinionsForPlayer = (minion: BoardEntity, input: SoCInput): boolean => {\r\n\tconst loops = input.playerEntity.trinkets?.some((t) => t.cardId === CardIds.ValdrakkenWindChimes_BG32_MagicItem_365)\r\n\t\t? 2\r\n\t\t: 1;\r\n\tlet hasProcessed = false;\r\n\tfor (let i = 0; i < loops; i++) {\r\n\t\tif (input.playerEntity.startOfCombatDone) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\thasProcessed = performStartOfCombatAction(minion.cardId, minion, input, true, undefined, false) || hasProcessed;\r\n\t\t// Dark Gifts are enchantments on the minion, and the ones with a custom effect implement it via the\r\n\t\t// enchantment card id, with the host minion as the acting entity\r\n\t\tfor (const enchantment of minion.enchantments ?? []) {\r\n\t\t\thasProcessed =\r\n\t\t\t\tperformStartOfCombatAction(enchantment.cardId, minion, input, true, undefined, false) || hasProcessed;\r\n\t\t}\r\n\t}\r\n\treturn hasProcessed;\r\n};\r\n"]}
1
+ {"version":3,"file":"soc-minion.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/soc-minion.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsPlayerEntity } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { hasStartOfCombatFromHand } from '../../cards/card.interface';\r\nimport { cardMappings } from '../../cards/impl/_card-mappings';\r\nimport { CardIds } from '../../services/card-ids';\r\nimport { FullGameState } from '../internal-game-state';\r\nimport { performStartOfCombatAction } from './soc-action-processor';\r\nimport { SoCInput } from './start-of-combat-input';\r\n\r\nexport const 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\tgameState: FullGameState,\r\n): number => {\r\n\tlet attackerForStart = Math.random() < 0.5 ? 0 : 1;\r\n\tconst playerAttackers = [\r\n\t\t// Hand triggers first\r\n\t\t...playerEntity.hand.filter((e) => hasStartOfCombatFromHand(cardMappings[e.cardId])),\r\n\t\t...playerBoard,\r\n\t];\r\n\tconst opponentAttackers = [\r\n\t\t...opponentEntity.hand.filter((e) => hasStartOfCombatFromHand(cardMappings[e.cardId])),\r\n\t\t...opponentBoard,\r\n\t];\r\n\r\n\t// UPDATE 2025-11-16 We probably want to run the Start of Combat first for one player completely, then for the other\r\n\t// I thought it would alternate, but this apparently isn't the case:\r\n\t// https://replays.firestoneapp.com/?reviewId=af9053ee-9ee6-440a-a09f-b7fb2f4b7a3e&turn=9&action=0\r\n\twhile (playerAttackers.length > 0 || opponentAttackers.length > 0) {\r\n\t\tlet shouldUpdateNextPlayer = false;\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\tconst input = {\r\n\t\t\t\tplayerBoard: playerBoard,\r\n\t\t\t\tplayerEntity: playerEntity,\r\n\t\t\t\topponentBoard: opponentBoard,\r\n\t\t\t\topponentEntity: opponentEntity,\r\n\t\t\t\tplayerBoardBefore: playerBoardBefore,\r\n\t\t\t\topponentBoardBefore: opponentBoardBefore,\r\n\t\t\t\tplayerIsFriendly: true,\r\n\t\t\t\tcurrentAttacker: currentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t};\r\n\t\t\tconst newShouldUpdateNextPlayer = performStartOfCombatMinionsForPlayer(attacker, input);\r\n\t\t\tcurrentAttacker = input.currentAttacker;\r\n\t\t} else if (attackerForStart === 0 && playerAttackers.length === 0) {\r\n\t\t\tshouldUpdateNextPlayer = true;\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\tconst input = {\r\n\t\t\t\tplayerBoard: opponentBoard,\r\n\t\t\t\tplayerEntity: opponentEntity,\r\n\t\t\t\topponentBoard: playerBoard,\r\n\t\t\t\topponentEntity: playerEntity,\r\n\t\t\t\tplayerBoardBefore: opponentBoardBefore,\r\n\t\t\t\topponentBoardBefore: playerBoardBefore,\r\n\t\t\t\tplayerIsFriendly: false,\r\n\t\t\t\tcurrentAttacker: currentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t};\r\n\t\t\tconst newShouldUpdateNextPlayer = performStartOfCombatMinionsForPlayer(attacker, input);\r\n\t\t\tcurrentAttacker = input.currentAttacker;\r\n\t\t} else if (attackerForStart === 1 && opponentAttackers.length === 0) {\r\n\t\t\tshouldUpdateNextPlayer = true;\r\n\t\t}\r\n\r\n\t\tif (shouldUpdateNextPlayer) {\r\n\t\t\tattackerForStart = (attackerForStart + 1) % 2;\r\n\t\t}\r\n\t}\r\n\t// 2026-09-29: I'm having doubts as to whether the \"summonsWhenSpace\" should be called here.\r\n\t// https://replays.firestoneapp.com/?reviewId=71184008-9884-47d0-89fc-c175c37a3be3&turn=15&action=1\r\n\t// Bomm-in-a-Box triggers, then the player attacks, and only the does Tentacular procs\r\n\t// https://replays.firestoneapp.com/?reviewId=49582580-dae9-4079-b2ff-741bab446da6&turn=27&action=2\r\n\t// On this board, Heroic Broodmother attacks twice as part of the Start of Combat, then the\r\n\t// opponent's turn starts and it attacks immediately before giving Frostwolf Fervor a chance to proc\r\n\t// For now I will comment this out, and we'll see how that goes\r\n\t// const shouldRecomputeCurrentAttacker = handleSummonsWhenSpace(\r\n\t// \tplayerBoard,\r\n\t// \tplayerEntity,\r\n\t// \topponentBoard,\r\n\t// \topponentEntity,\r\n\t// \tgameState,\r\n\t// );\r\n\t// if (shouldRecomputeCurrentAttacker) {\r\n\t// \tcurrentAttacker =\r\n\t// \t\tplayerBoard.length > opponentBoard.length\r\n\t// \t\t\t? 0\r\n\t// \t\t\t: opponentBoard.length > playerBoard.length\r\n\t// \t\t\t? 1\r\n\t// \t\t\t: Math.round(Math.random());\r\n\t// }\r\n\treturn currentAttacker;\r\n};\r\n\r\n// Apparently, the board composition used for start of combat minion effects (like Red Whelp, and I assume it works the\r\n// 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// 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// Tamsin's Phylactery.\r\nexport const performStartOfCombatMinionsForPlayer = (minion: BoardEntity, input: SoCInput): boolean => {\r\n\tconst loops = input.playerEntity.trinkets?.some((t) => t.cardId === CardIds.ValdrakkenWindChimes_BG32_MagicItem_365)\r\n\t\t? 2\r\n\t\t: 1;\r\n\tlet hasProcessed = false;\r\n\tfor (let i = 0; i < loops; i++) {\r\n\t\tif (input.playerEntity.startOfCombatDone) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\thasProcessed = performStartOfCombatAction(minion.cardId, minion, input, true, undefined) || hasProcessed;\r\n\t\t// Dark Gifts are enchantments on the minion, and the ones with a custom effect implement it via the\r\n\t\t// enchantment card id, with the host minion as the acting entity\r\n\t\tfor (const enchantment of minion.enchantments ?? []) {\r\n\t\t\thasProcessed =\r\n\t\t\t\tperformStartOfCombatAction(enchantment.cardId, minion, input, true, undefined) || hasProcessed;\r\n\t\t}\r\n\t}\r\n\treturn hasProcessed;\r\n};\r\n"]}
@@ -215,6 +215,7 @@ const handleBoonOfBeetlesForPlayer = (playerBoard, playerEntity, opponentBoard,
215
215
  (0, taunt_1.updateTaunt)(entity, true, playerBoard, playerEntity, opponentEntity, gameState);
216
216
  });
217
217
  secretEntity.triggersLeft--;
218
+ return true;
218
219
  }
219
220
  else {
220
221
  break;
@@ -253,6 +254,9 @@ const handleSummon = (playerBoard, playerEntity, opponentBoard, opponentEntity,
253
254
  }
254
255
  const newMinion = (0, utils_2.buildSingleBoardEntity)(cardId, playerEntity, playerBoard, gameState.allCards, playerEntity.friendly, gameState.sharedState.currentEntityId++, false, gameState.cardsData, gameState.sharedState, minion, null);
255
256
  const spawned = (0, spawns_1.performEntitySpawns)([newMinion], playerBoard, playerEntity, playerEntity, indexFromRight, opponentBoard, opponentEntity, gameState, applyAuras);
257
+ if (playerBoard.indexOf(newMinion) === 0) {
258
+ newMinion.hasAttacked = playerEntity.leftMostAttacked;
259
+ }
256
260
  gameState.spectator.registerPowerTarget(playerEntity, newMinion, playerBoard, null, null);
257
261
  return spawned;
258
262
  };
@@ -1 +1 @@
1
- {"version":3,"file":"summon-when-space.js","sourceRoot":"","sources":["../../src/simulation/summon-when-space.ts"],"names":[],"mappings":"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","sourcesContent":["import { Race } from '@firestone-hs/reference-data';\r\nimport { BgsHeroPower, BgsPlayerEntity, BoardTrinket } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { handleDiremuckPendingSummons } from '../cards/impl/minion/diremuck-forager';\r\nimport { handleAutomatonPortraitForPlayer } from '../cards/impl/trinket/automaton-portrait';\r\nimport { updateTaunt } from '../keywords/taunt';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickRandomHighestAttack, pickRandomHighestHealth } from '../services/utils';\r\nimport { buildSingleBoardEntity, copyEntity, hasCorrectTribe } from '../utils';\r\nimport { removeAurasFromSelf } from './add-minion-to-board';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { performEntitySpawns } from './spawns';\r\n\r\nexport const handleSummonsWhenSpace = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): boolean => {\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\tif (Math.random() < 0.5) {\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleSummonsWhenSpaceForPlayer(\r\n\t\t\t\tplayerEntity,\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\tgameState,\r\n\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleSummonsWhenSpaceForPlayer(\r\n\t\t\t\topponentEntity,\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\tgameState,\r\n\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t} else {\r\n\t\tshouldRecomputeCurrentAttacker = handleSummonsWhenSpaceForPlayer(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleSummonsWhenSpaceForPlayer(\r\n\t\t\t\tplayerEntity,\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\tgameState,\r\n\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t}\r\n\treturn shouldRecomputeCurrentAttacker;\r\n};\r\n\r\n// TODO: Twin Sky Lanterns wait for 2 spaces\r\nconst handleSummonsWhenSpaceForPlayer = (\r\n\ttargetEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): boolean => {\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\tif (targetEntity.questRewards?.includes(CardIds.StableAmalgamation_BG28_Reward_518)) {\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleStableAmalgamationForPlayer(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState) ||\r\n\t\t\tshouldRecomputeCurrentAttacker;\r\n\t}\r\n\tif (targetEntity.secrets?.some((s) => s.cardId === CardIds.BoonOfBeetles_BG28_603)) {\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleBoonOfBeetlesForPlayer(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState) ||\r\n\t\t\tshouldRecomputeCurrentAttacker;\r\n\t}\r\n\tfor (const heroPower of targetEntity.heroPowers) {\r\n\t\tif (heroPower.cardId === CardIds.Ozumat_Tentacular && heroPower.ready) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleOzumatForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.Drekthar_LeadTheFrostwolves &&\r\n\t\t\tgameState.currentTurn >= 7 &&\r\n\t\t\theroPower.ready &&\r\n\t\t\t!heroPower.activated\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleFrostwolfFervorForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.VanndarStormpike_LeadTheStormpikes &&\r\n\t\t\tgameState.currentTurn >= 7 &&\r\n\t\t\theroPower.ready &&\r\n\t\t\t!heroPower.activated\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleStormpikeStrengthForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.LockAndLoadToken_BG22_HERO_000p_Alt &&\r\n\t\t\t!heroPower.activated &&\r\n\t\t\theroPower.ready\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\t!!handleLockAndLoadForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.TeronGorefiend_RapidReanimation &&\r\n\t\t\t(heroPower.info as BoardEntity)?.cardId\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleRapidReanimationForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t}\r\n\t}\r\n\tfor (const t of targetEntity.trinkets) {\r\n\t\tif (\r\n\t\t\tt.cardId === CardIds.TwinSkyLanterns_BG30_MagicItem_822 ||\r\n\t\t\tt.cardId === CardIds.TwinSkyLanterns_TwinSkyLanternsToken_BG30_MagicItem_822t2\r\n\t\t) {\r\n\t\t\thandleTwinSkyLanternsForPlayer(t, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t}\r\n\t}\r\n\tfor (const t of targetEntity.trinkets) {\r\n\t\tif (t.cardId === CardIds.BoomController_BG30_MagicItem_440) {\r\n\t\t\thandleBoomControllerForPlayer(t, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t}\r\n\t}\r\n\tfor (const t of targetEntity.trinkets) {\r\n\t\tif (t.cardId === CardIds.AutomatonPortrait_BG30_MagicItem_303) {\r\n\t\t\thandleAutomatonPortraitForPlayer(t, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t}\r\n\t}\r\n\t// some() first to avoid the snapshot allocation in the common case where no snapper is present\r\n\tif (\r\n\t\tplayerBoard.some(\r\n\t\t\t(e) => e.cardId === CardIds.SharptoothSnapper_BG32_201 || e.cardId === CardIds.SharptoothSnapper_BG32_201_G,\r\n\t\t)\r\n\t) {\r\n\t\tplayerBoard\r\n\t\t\t.filter(\r\n\t\t\t\t(e) =>\r\n\t\t\t\t\te.cardId === CardIds.SharptoothSnapper_BG32_201 ||\r\n\t\t\t\t\te.cardId === CardIds.SharptoothSnapper_BG32_201_G,\r\n\t\t\t)\r\n\t\t\t.forEach((e) => {\r\n\t\t\t\thandleSharptoothSnapperForPlayer(\r\n\t\t\t\t\te,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t});\r\n\t}\r\n\thandleDiremuckPendingSummons(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\treturn shouldRecomputeCurrentAttacker;\r\n};\r\n\r\nexport const handleSharptoothSnapperForPlayer = (\r\n\tentity: BoardEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\twhile (playerBoard.length < 7 && entity.abiityChargesLeft > 0) {\r\n\t\tconst candidates = spawnEntities(\r\n\t\t\tCardIds.SharptoothSnapper_PiranhaToken_BG32_201t,\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\tgameState,\r\n\t\t\tplayerEntity.friendly,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t\tcandidates.forEach((t) => (t.attackImmediately = true));\r\n\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\tcandidates,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard.length - 1 - playerBoard.indexOf(entity),\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tentity.abiityChargesLeft--;\r\n\t}\r\n};\r\n\r\nconst handleBoomControllerForPlayer = (\r\n\ttrinket: BoardTrinket,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (playerBoard.length < 7 && trinket.scriptDataNum1 > 0) {\r\n\t\tconst candidate = gameState.sharedState.deaths\r\n\t\t\t.filter((d) => d.friendly === playerEntity.friendly)\r\n\t\t\t.filter((d) => hasCorrectTribe(d, playerEntity, Race.MECH, gameState.anomalies, gameState.allCards))[0];\r\n\t\tif (!!candidate) {\r\n\t\t\tconst spawn = copyEntity(candidate);\r\n\t\t\tremoveAurasFromSelf(spawn, playerBoard, playerEntity, gameState);\r\n\t\t\tconst initialIndexFromLeft = candidate.indexFromLeftAtTimeOfDeath;\r\n\t\t\tconst indexFromRight =\r\n\t\t\t\tinitialIndexFromLeft == null\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: Math.min(playerBoard.length, Math.max(0, playerBoard.length - initialIndexFromLeft));\r\n\t\t\tconst target = spawnEntities(\r\n\t\t\t\tspawn.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\ttrue,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tspawn,\r\n\t\t\t);\r\n\t\t\t// FIXME: here it should try to match the position at which the original minions died\r\n\t\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\t\ttarget,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tactualSpawns.forEach((t) =>\r\n\t\t\t\tgameState.spectator.registerPowerTarget(playerEntity, t, playerBoard, playerEntity, opponentEntity),\r\n\t\t\t);\r\n\t\t\ttrinket.scriptDataNum1 = 0;\r\n\t\t\t// It summons an exact copy\r\n\t\t\t// actualSpawns.forEach((entity) => {\r\n\t\t\t// \tswitch (entity.cardId) {\r\n\t\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401:\r\n\t\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401_G:\r\n\t\t\t// \t\t\tconst overstatMult = entity.cardId === CardIds.AstralAutomaton_BG_TTN_401 ? 1 : 2;\r\n\t\t\t// \t\t\tentity.attack = Math.max(1, entity.attack - 2 * overstatMult);\r\n\t\t\t// \t\t\tentity.health = Math.max(0, entity.health - overstatMult);\r\n\t\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\r\nconst handleTwinSkyLanternsForPlayer = (\r\n\ttrinket: BoardTrinket,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst spawnNumber = trinket.scriptDataNum1 ?? 0;\r\n\tconst canTrigger = spawnNumber >= 1;\r\n\tif (playerBoard.length <= 7 - spawnNumber && trinket.rememberedMinions?.length && canTrigger) {\r\n\t\ttrinket.scriptDataNum1 = 0;\r\n\t\tconst spawn = copyEntity(trinket.rememberedMinions[0]);\r\n\t\tremoveAurasFromSelf(spawn, playerBoard, playerEntity, gameState);\r\n\t\tconst target = spawnEntities(\r\n\t\t\tspawn.cardId,\r\n\t\t\tspawnNumber,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tgameState,\r\n\t\t\tplayerEntity.friendly,\r\n\t\t\ttrue,\r\n\t\t\tfalse,\r\n\t\t\tfalse,\r\n\t\t\tspawn,\r\n\t\t);\r\n\t\tperformEntitySpawns(\r\n\t\t\ttarget,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerEntity,\r\n\t\t\t0,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\ttarget.forEach((t) =>\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, t, playerBoard, playerEntity, opponentEntity),\r\n\t\t);\r\n\t}\r\n};\r\n\r\nconst handleOzumatForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7 && heroPower.activated === false) {\r\n\t\tconst tentacularSize = +heroPower.info;\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\tgameState,\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\ttentacular[0].maxHealth = tentacularSize;\r\n\t\ttentacular[0].maxAttack = 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\tgameState,\r\n\t\t);\r\n\t\tgameState.spectator.registerPowerTarget(playerEntity, tentacular[0], playerBoard, playerEntity, opponentEntity);\r\n\t\theroPower.activated = true;\r\n\t}\r\n\t// UPDATE 2026-08-26 first attacker is recomputed after the summon\r\n\t// https://replays.firestoneapp.com/?reviewId=a5faefd8-c04f-48ae-bc41-540ee8f7e8ce&turn=9&action=2\r\n\t// (it becomes 3 vs 3 after the summon, so Ozumat's controller can become first attacker)\r\n\treturn true;\r\n};\r\n\r\nconst handleFrostwolfFervorForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7) {\r\n\t\theroPower.activated = true;\r\n\t\tconst target = pickRandomHighestAttack(playerBoard);\r\n\t\tif (!!target) {\r\n\t\t\tconst copy = copyEntity(target);\r\n\t\t\tremoveAurasFromSelf(copy, playerBoard, playerEntity, gameState);\r\n\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(target) + 1);\r\n\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\tcopy.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tcopy,\r\n\t\t\t);\r\n\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\tnewMinions,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tspawns.forEach((e) => (e.hasAttacked = target.hasAttacked));\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, spawns[0], playerBoard, playerEntity, opponentEntity);\r\n\t\t\t// 33.6.2 https://replays.firestoneapp.com/?reviewId=35bc0472-b915-4fa3-8d29-8a8d4d806745&turn=15&action=2\r\n\t\t\treturn true;\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleLockAndLoadForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7) {\r\n\t\tconst summoned = heroPower.info as BoardEntity;\r\n\t\theroPower.activated = true;\r\n\t\tif (!!summoned?.cardId) {\r\n\t\t\tconst copy = copyEntity(summoned);\r\n\t\t\tremoveAurasFromSelf(copy, playerBoard, playerEntity, gameState);\r\n\t\t\tcopy.attackImmediately = true;\r\n\t\t\tconst indexFromRight = 0;\r\n\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\tcopy.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tcopy,\r\n\t\t\t);\r\n\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\tnewMinions,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, spawns[0], playerBoard, playerEntity, opponentEntity);\r\n\t\t\t// Do the attack right now, so that we can recompute the first attacker once the attack resolves\r\n\t\t\t// Attack is actually performed with the \"performEntitySpawns\" function\r\n\t\t\t// simulateAttack(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t\t// 33.6 https://replays.firestoneapp.com/?reviewId=441da83c-3e40-4630-b98f-caf1932e5be7&turn=11&action=0\r\n\t\t\t// The minion needs to go back to the normal attacking order\r\n\t\t\t// 34.0 https://replays.firestoneapp.com/?reviewId=6902bbda-cd04-4e2d-9643-3c87534e0986&turn=7&action=3\r\n\t\t\t// Can be null if it dies after being spawned\r\n\t\t\tif (spawns[0]) {\r\n\t\t\t\tspawns[0].hasAttacked = undefined;\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handleStormpikeStrengthForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7) {\r\n\t\theroPower.activated = true;\r\n\t\tconst target = pickRandomHighestHealth(playerBoard);\r\n\t\tif (!!target) {\r\n\t\t\tconst copy = copyEntity(target);\r\n\t\t\tremoveAurasFromSelf(copy, playerBoard, playerEntity, gameState);\r\n\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(target) + 1);\r\n\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\tcopy.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tcopy,\r\n\t\t\t);\r\n\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\tnewMinions,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, spawns[0], playerBoard, playerEntity, opponentEntity);\r\n\t\t\t// 33.6.2 https://replays.firestoneapp.com/?reviewId=35bc0472-b915-4fa3-8d29-8a8d4d806745&turn=15&action=2\r\n\t\t\treturn true;\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleBoonOfBeetlesForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst secretEntity = playerEntity.secrets.find((entity) => entity.cardId === CardIds.BoonOfBeetles_BG28_603);\r\n\tif (secretEntity && secretEntity.triggersLeft > 0) {\r\n\t\twhile (secretEntity.triggersLeft > 0) {\r\n\t\t\tconst hasSummoned = handleSummon(\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\tgameState,\r\n\t\t\t\tCardIds.BoonOfBeetles_BeetleToken_BG28_603t,\r\n\t\t\t\t0,\r\n\t\t\t\ttrue,\r\n\t\t\t);\r\n\t\t\tif (hasSummoned) {\r\n\t\t\t\thasSummoned.forEach((entity) => {\r\n\t\t\t\t\tupdateTaunt(entity, true, playerBoard, playerEntity, opponentEntity, gameState);\r\n\t\t\t\t});\r\n\t\t\t\tsecretEntity.triggersLeft--;\r\n\t\t\t} else {\r\n\t\t\t\t// No room to summon, we stop here\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\nconst handleStableAmalgamationForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst rewardEntity = playerEntity.questRewardEntities.find(\r\n\t\t(entity) => entity.cardId === CardIds.StableAmalgamation_BG28_Reward_518,\r\n\t);\r\n\tif (rewardEntity && rewardEntity.scriptDataNum1 > 0) {\r\n\t\twhile (rewardEntity.scriptDataNum1 > 0) {\r\n\t\t\tconst hasSummoned = handleSummon(\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\tgameState,\r\n\t\t\t\tCardIds.StableAmalgamation_TotallyNormalHorseToken_BG28_Reward_518t,\r\n\t\t\t\t0,\r\n\t\t\t\ttrue,\r\n\t\t\t);\r\n\t\t\tif (hasSummoned) {\r\n\t\t\t\trewardEntity.scriptDataNum1--;\r\n\t\t\t} else {\r\n\t\t\t\t// No room to summon, we stop here\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleRapidReanimationForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\t// 2026-01-08: When the sacrificed minion is the far-right one, we want to resurrect it there\r\n\t// https://replays.firestoneapp.com/?reviewId=4e5d8239-2d8d-41db-9b8f-35b5179c28fb&turn=7&action=4\r\n\tconst indexFromRight = heroPower.info2;\r\n\tconst rapidReanimationMinion = heroPower.info as BoardEntity;\r\n\tconst hasSummoned = handleSummon(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tgameState,\r\n\t\trapidReanimationMinion.cardId,\r\n\t\tindexFromRight,\r\n\t\ttrue, // (Goldrinn gets buffed, so it seems we reapply auras? This is a mess tbh)\r\n\t\trapidReanimationMinion,\r\n\t);\r\n\tif (hasSummoned) {\r\n\t\theroPower.info = null;\r\n\t\t// Hard-coding a correction for Ancestral Automaton\r\n\t\t// Shold not be necessary if we reapply auras\r\n\t\t// hasSummoned.forEach((entity) => {\r\n\t\t// \tswitch (entity.cardId) {\r\n\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401:\r\n\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401_G:\r\n\t\t// \t\t\tconst overstatMult = entity.cardId === CardIds.AstralAutomaton_BG_TTN_401 ? 1 : 2;\r\n\t\t// \t\t\tentity.attack = Math.max(1, entity.attack + 2 * overstatMult);\r\n\t\t// \t\t\tentity.health = Math.max(0, entity.health + 2 * overstatMult);\r\n\t\t// \t\t\tbreak;\r\n\t\t// \t\tcase CardIds.EternalKnight_BG25_008:\r\n\t\t// \t\tcase CardIds.EternalKnight_BG25_008_G:\r\n\t\t// \t\t\tconst knightMult = entity.cardId === CardIds.EternalKnight_BG25_008 ? 1 : 2;\r\n\t\t// \t\t\tentity.attack = Math.max(1, entity.attack + 1 * knightMult);\r\n\t\t// \t\t\tentity.health = Math.max(0, entity.health + 1 * knightMult);\r\n\t\t// \t\t\tbreak;\r\n\t\t// \t}\r\n\t\t// });\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleSummon = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tcardId: string,\r\n\tindexFromRight: number,\r\n\tapplyAuras: boolean,\r\n\tminion: BoardEntity = null,\r\n): readonly BoardEntity[] => {\r\n\tif (playerBoard.length >= 7) {\r\n\t\treturn null;\r\n\t}\r\n\tconst newMinion = buildSingleBoardEntity(\r\n\t\tcardId,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tgameState.allCards,\r\n\t\tplayerEntity.friendly,\r\n\t\tgameState.sharedState.currentEntityId++,\r\n\t\tfalse,\r\n\t\tgameState.cardsData,\r\n\t\tgameState.sharedState,\r\n\t\tminion,\r\n\t\tnull,\r\n\t);\r\n\t// Don't reapply auras in this particular case? See https://x.com/ZerotoHeroes_HS/status/1737422727118487808?s=20\r\n\tconst spawned = performEntitySpawns(\r\n\t\t[newMinion],\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerEntity,\r\n\t\tindexFromRight,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tgameState,\r\n\t\tapplyAuras,\r\n\t);\r\n\tgameState.spectator.registerPowerTarget(playerEntity, newMinion, playerBoard, null, null);\r\n\treturn spawned;\r\n};\r\n"]}
1
+ {"version":3,"file":"summon-when-space.js","sourceRoot":"","sources":["../../src/simulation/summon-when-space.ts"],"names":[],"mappings":"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","sourcesContent":["import { Race } from '@firestone-hs/reference-data';\r\nimport { BgsHeroPower, BgsPlayerEntity, BoardTrinket } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { handleDiremuckPendingSummons } from '../cards/impl/minion/diremuck-forager';\r\nimport { handleAutomatonPortraitForPlayer } from '../cards/impl/trinket/automaton-portrait';\r\nimport { updateTaunt } from '../keywords/taunt';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickRandomHighestAttack, pickRandomHighestHealth } from '../services/utils';\r\nimport { buildSingleBoardEntity, copyEntity, hasCorrectTribe } from '../utils';\r\nimport { removeAurasFromSelf } from './add-minion-to-board';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { performEntitySpawns } from './spawns';\r\n\r\nexport const handleSummonsWhenSpace = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): boolean => {\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\tif (Math.random() < 0.5) {\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleSummonsWhenSpaceForPlayer(\r\n\t\t\t\tplayerEntity,\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\tgameState,\r\n\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleSummonsWhenSpaceForPlayer(\r\n\t\t\t\topponentEntity,\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\tgameState,\r\n\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t} else {\r\n\t\tshouldRecomputeCurrentAttacker = handleSummonsWhenSpaceForPlayer(\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleSummonsWhenSpaceForPlayer(\r\n\t\t\t\tplayerEntity,\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\tgameState,\r\n\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t}\r\n\treturn shouldRecomputeCurrentAttacker;\r\n};\r\n\r\n// TODO: Twin Sky Lanterns wait for 2 spaces\r\nconst handleSummonsWhenSpaceForPlayer = (\r\n\ttargetEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): boolean => {\r\n\tlet shouldRecomputeCurrentAttacker = false;\r\n\tif (targetEntity.questRewards?.includes(CardIds.StableAmalgamation_BG28_Reward_518)) {\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleStableAmalgamationForPlayer(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState) ||\r\n\t\t\tshouldRecomputeCurrentAttacker;\r\n\t}\r\n\tif (targetEntity.secrets?.some((s) => s.cardId === CardIds.BoonOfBeetles_BG28_603)) {\r\n\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\thandleBoonOfBeetlesForPlayer(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState) ||\r\n\t\t\tshouldRecomputeCurrentAttacker;\r\n\t}\r\n\tfor (const heroPower of targetEntity.heroPowers) {\r\n\t\tif (heroPower.cardId === CardIds.Ozumat_Tentacular && heroPower.ready) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleOzumatForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.Drekthar_LeadTheFrostwolves &&\r\n\t\t\tgameState.currentTurn >= 7 &&\r\n\t\t\theroPower.ready &&\r\n\t\t\t!heroPower.activated\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleFrostwolfFervorForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.VanndarStormpike_LeadTheStormpikes &&\r\n\t\t\tgameState.currentTurn >= 7 &&\r\n\t\t\theroPower.ready &&\r\n\t\t\t!heroPower.activated\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleStormpikeStrengthForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.LockAndLoadToken_BG22_HERO_000p_Alt &&\r\n\t\t\t!heroPower.activated &&\r\n\t\t\theroPower.ready\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\t!!handleLockAndLoadForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\ttargetEntity.friendly,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t} else if (\r\n\t\t\theroPower.cardId === CardIds.TeronGorefiend_RapidReanimation &&\r\n\t\t\t(heroPower.info as BoardEntity)?.cardId\r\n\t\t) {\r\n\t\t\tshouldRecomputeCurrentAttacker =\r\n\t\t\t\thandleRapidReanimationForPlayer(\r\n\t\t\t\t\theroPower,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t) || shouldRecomputeCurrentAttacker;\r\n\t\t}\r\n\t}\r\n\tfor (const t of targetEntity.trinkets) {\r\n\t\tif (\r\n\t\t\tt.cardId === CardIds.TwinSkyLanterns_BG30_MagicItem_822 ||\r\n\t\t\tt.cardId === CardIds.TwinSkyLanterns_TwinSkyLanternsToken_BG30_MagicItem_822t2\r\n\t\t) {\r\n\t\t\thandleTwinSkyLanternsForPlayer(t, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t}\r\n\t}\r\n\tfor (const t of targetEntity.trinkets) {\r\n\t\tif (t.cardId === CardIds.BoomController_BG30_MagicItem_440) {\r\n\t\t\thandleBoomControllerForPlayer(t, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t}\r\n\t}\r\n\tfor (const t of targetEntity.trinkets) {\r\n\t\tif (t.cardId === CardIds.AutomatonPortrait_BG30_MagicItem_303) {\r\n\t\t\thandleAutomatonPortraitForPlayer(t, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t}\r\n\t}\r\n\t// some() first to avoid the snapshot allocation in the common case where no snapper is present\r\n\tif (\r\n\t\tplayerBoard.some(\r\n\t\t\t(e) => e.cardId === CardIds.SharptoothSnapper_BG32_201 || e.cardId === CardIds.SharptoothSnapper_BG32_201_G,\r\n\t\t)\r\n\t) {\r\n\t\tplayerBoard\r\n\t\t\t.filter(\r\n\t\t\t\t(e) =>\r\n\t\t\t\t\te.cardId === CardIds.SharptoothSnapper_BG32_201 ||\r\n\t\t\t\t\te.cardId === CardIds.SharptoothSnapper_BG32_201_G,\r\n\t\t\t)\r\n\t\t\t.forEach((e) => {\r\n\t\t\t\thandleSharptoothSnapperForPlayer(\r\n\t\t\t\t\te,\r\n\t\t\t\t\tplayerBoard,\r\n\t\t\t\t\tplayerEntity,\r\n\t\t\t\t\topponentBoard,\r\n\t\t\t\t\topponentEntity,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t);\r\n\t\t\t});\r\n\t}\r\n\thandleDiremuckPendingSummons(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\treturn shouldRecomputeCurrentAttacker;\r\n};\r\n\r\nexport const handleSharptoothSnapperForPlayer = (\r\n\tentity: BoardEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\twhile (playerBoard.length < 7 && entity.abiityChargesLeft > 0) {\r\n\t\tconst candidates = spawnEntities(\r\n\t\t\tCardIds.SharptoothSnapper_PiranhaToken_BG32_201t,\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\tgameState,\r\n\t\t\tplayerEntity.friendly,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t\tcandidates.forEach((t) => (t.attackImmediately = true));\r\n\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\tcandidates,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard.length - 1 - playerBoard.indexOf(entity),\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tentity.abiityChargesLeft--;\r\n\t}\r\n};\r\n\r\nconst handleBoomControllerForPlayer = (\r\n\ttrinket: BoardTrinket,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (playerBoard.length < 7 && trinket.scriptDataNum1 > 0) {\r\n\t\tconst candidate = gameState.sharedState.deaths\r\n\t\t\t.filter((d) => d.friendly === playerEntity.friendly)\r\n\t\t\t.filter((d) => hasCorrectTribe(d, playerEntity, Race.MECH, gameState.anomalies, gameState.allCards))[0];\r\n\t\tif (!!candidate) {\r\n\t\t\tconst spawn = copyEntity(candidate);\r\n\t\t\tremoveAurasFromSelf(spawn, playerBoard, playerEntity, gameState);\r\n\t\t\tconst initialIndexFromLeft = candidate.indexFromLeftAtTimeOfDeath;\r\n\t\t\tconst indexFromRight =\r\n\t\t\t\tinitialIndexFromLeft == null\r\n\t\t\t\t\t? 0\r\n\t\t\t\t\t: Math.min(playerBoard.length, Math.max(0, playerBoard.length - initialIndexFromLeft));\r\n\t\t\tconst target = spawnEntities(\r\n\t\t\t\tspawn.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\ttrue,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tspawn,\r\n\t\t\t);\r\n\t\t\t// FIXME: here it should try to match the position at which the original minions died\r\n\t\t\tconst actualSpawns = performEntitySpawns(\r\n\t\t\t\ttarget,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tactualSpawns.forEach((t) =>\r\n\t\t\t\tgameState.spectator.registerPowerTarget(playerEntity, t, playerBoard, playerEntity, opponentEntity),\r\n\t\t\t);\r\n\t\t\ttrinket.scriptDataNum1 = 0;\r\n\t\t\t// It summons an exact copy\r\n\t\t\t// actualSpawns.forEach((entity) => {\r\n\t\t\t// \tswitch (entity.cardId) {\r\n\t\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401:\r\n\t\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401_G:\r\n\t\t\t// \t\t\tconst overstatMult = entity.cardId === CardIds.AstralAutomaton_BG_TTN_401 ? 1 : 2;\r\n\t\t\t// \t\t\tentity.attack = Math.max(1, entity.attack - 2 * overstatMult);\r\n\t\t\t// \t\t\tentity.health = Math.max(0, entity.health - overstatMult);\r\n\t\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\r\nconst handleTwinSkyLanternsForPlayer = (\r\n\ttrinket: BoardTrinket,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst spawnNumber = trinket.scriptDataNum1 ?? 0;\r\n\tconst canTrigger = spawnNumber >= 1;\r\n\tif (playerBoard.length <= 7 - spawnNumber && trinket.rememberedMinions?.length && canTrigger) {\r\n\t\ttrinket.scriptDataNum1 = 0;\r\n\t\tconst spawn = copyEntity(trinket.rememberedMinions[0]);\r\n\t\tremoveAurasFromSelf(spawn, playerBoard, playerEntity, gameState);\r\n\t\tconst target = spawnEntities(\r\n\t\t\tspawn.cardId,\r\n\t\t\tspawnNumber,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tgameState,\r\n\t\t\tplayerEntity.friendly,\r\n\t\t\ttrue,\r\n\t\t\tfalse,\r\n\t\t\tfalse,\r\n\t\t\tspawn,\r\n\t\t);\r\n\t\tperformEntitySpawns(\r\n\t\t\ttarget,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerEntity,\r\n\t\t\t0,\r\n\t\t\topponentBoard,\r\n\t\t\topponentEntity,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\ttarget.forEach((t) =>\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, t, playerBoard, playerEntity, opponentEntity),\r\n\t\t);\r\n\t}\r\n};\r\n\r\nconst handleOzumatForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7 && heroPower.activated === false) {\r\n\t\tconst tentacularSize = +heroPower.info;\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\tgameState,\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\ttentacular[0].maxHealth = tentacularSize;\r\n\t\ttentacular[0].maxAttack = 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\tgameState,\r\n\t\t);\r\n\t\tgameState.spectator.registerPowerTarget(playerEntity, tentacular[0], playerBoard, playerEntity, opponentEntity);\r\n\t\theroPower.activated = true;\r\n\t}\r\n\t// UPDATE 2026-08-26 first attacker is recomputed after the summon\r\n\t// https://replays.firestoneapp.com/?reviewId=a5faefd8-c04f-48ae-bc41-540ee8f7e8ce&turn=9&action=2\r\n\t// (it becomes 3 vs 3 after the summon, so Ozumat's controller can become first attacker)\r\n\treturn true;\r\n};\r\n\r\nconst handleFrostwolfFervorForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7) {\r\n\t\theroPower.activated = true;\r\n\t\tconst target = pickRandomHighestAttack(playerBoard);\r\n\t\tif (!!target) {\r\n\t\t\tconst copy = copyEntity(target);\r\n\t\t\tremoveAurasFromSelf(copy, playerBoard, playerEntity, gameState);\r\n\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(target) + 1);\r\n\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\tcopy.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tcopy,\r\n\t\t\t);\r\n\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\tnewMinions,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tspawns.forEach((e) => (e.hasAttacked = target.hasAttacked));\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, spawns[0], playerBoard, playerEntity, opponentEntity);\r\n\t\t\t// 33.6.2 https://replays.firestoneapp.com/?reviewId=35bc0472-b915-4fa3-8d29-8a8d4d806745&turn=15&action=2\r\n\t\t\treturn true;\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleLockAndLoadForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7) {\r\n\t\tconst summoned = heroPower.info as BoardEntity;\r\n\t\theroPower.activated = true;\r\n\t\tif (!!summoned?.cardId) {\r\n\t\t\tconst copy = copyEntity(summoned);\r\n\t\t\tremoveAurasFromSelf(copy, playerBoard, playerEntity, gameState);\r\n\t\t\tcopy.attackImmediately = true;\r\n\t\t\tconst indexFromRight = 0;\r\n\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\tcopy.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tcopy,\r\n\t\t\t);\r\n\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\tnewMinions,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, spawns[0], playerBoard, playerEntity, opponentEntity);\r\n\t\t\t// Do the attack right now, so that we can recompute the first attacker once the attack resolves\r\n\t\t\t// Attack is actually performed with the \"performEntitySpawns\" function\r\n\t\t\t// simulateAttack(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\t\t\t// 33.6 https://replays.firestoneapp.com/?reviewId=441da83c-3e40-4630-b98f-caf1932e5be7&turn=11&action=0\r\n\t\t\t// The minion needs to go back to the normal attacking order\r\n\t\t\t// 34.0 https://replays.firestoneapp.com/?reviewId=6902bbda-cd04-4e2d-9643-3c87534e0986&turn=7&action=3\r\n\t\t\t// Can be null if it dies after being spawned\r\n\t\t\tif (spawns[0]) {\r\n\t\t\t\tspawns[0].hasAttacked = undefined;\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t}\r\n\t}\r\n};\r\n\r\nconst handleStormpikeStrengthForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tfriendly: boolean,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tif (playerBoard.length < 7) {\r\n\t\theroPower.activated = true;\r\n\t\tconst target = pickRandomHighestHealth(playerBoard);\r\n\t\tif (!!target) {\r\n\t\t\tconst copy = copyEntity(target);\r\n\t\t\tremoveAurasFromSelf(copy, playerBoard, playerEntity, gameState);\r\n\t\t\tconst indexFromRight = playerBoard.length - (playerBoard.indexOf(target) + 1);\r\n\t\t\tconst newMinions = spawnEntities(\r\n\t\t\t\tcopy.cardId,\r\n\t\t\t\t1,\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\tgameState,\r\n\t\t\t\tplayerEntity.friendly,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tfalse,\r\n\t\t\t\tcopy,\r\n\t\t\t);\r\n\t\t\tconst spawns = performEntitySpawns(\r\n\t\t\t\tnewMinions,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tindexFromRight,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\tgameState.spectator.registerPowerTarget(playerEntity, spawns[0], playerBoard, playerEntity, opponentEntity);\r\n\t\t\t// 33.6.2 https://replays.firestoneapp.com/?reviewId=35bc0472-b915-4fa3-8d29-8a8d4d806745&turn=15&action=2\r\n\t\t\treturn true;\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleBoonOfBeetlesForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst secretEntity = playerEntity.secrets.find((entity) => entity.cardId === CardIds.BoonOfBeetles_BG28_603);\r\n\tif (secretEntity && secretEntity.triggersLeft > 0) {\r\n\t\twhile (secretEntity.triggersLeft > 0) {\r\n\t\t\tconst hasSummoned = handleSummon(\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\tgameState,\r\n\t\t\t\tCardIds.BoonOfBeetles_BeetleToken_BG28_603t,\r\n\t\t\t\t0,\r\n\t\t\t\ttrue,\r\n\t\t\t);\r\n\t\t\tif (hasSummoned) {\r\n\t\t\t\thasSummoned.forEach((entity) => {\r\n\t\t\t\t\tupdateTaunt(entity, true, playerBoard, playerEntity, opponentEntity, gameState);\r\n\t\t\t\t});\r\n\t\t\t\tsecretEntity.triggersLeft--;\r\n\t\t\t\treturn true;\r\n\t\t\t} else {\r\n\t\t\t\t// No room to summon, we stop here\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\nconst handleStableAmalgamationForPlayer = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\tconst rewardEntity = playerEntity.questRewardEntities.find(\r\n\t\t(entity) => entity.cardId === CardIds.StableAmalgamation_BG28_Reward_518,\r\n\t);\r\n\tif (rewardEntity && rewardEntity.scriptDataNum1 > 0) {\r\n\t\twhile (rewardEntity.scriptDataNum1 > 0) {\r\n\t\t\tconst hasSummoned = handleSummon(\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\tgameState,\r\n\t\t\t\tCardIds.StableAmalgamation_TotallyNormalHorseToken_BG28_Reward_518t,\r\n\t\t\t\t0,\r\n\t\t\t\ttrue,\r\n\t\t\t);\r\n\t\t\tif (hasSummoned) {\r\n\t\t\t\trewardEntity.scriptDataNum1--;\r\n\t\t\t} else {\r\n\t\t\t\t// No room to summon, we stop here\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleRapidReanimationForPlayer = (\r\n\theroPower: BgsHeroPower,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n) => {\r\n\t// 2026-01-08: When the sacrificed minion is the far-right one, we want to resurrect it there\r\n\t// https://replays.firestoneapp.com/?reviewId=4e5d8239-2d8d-41db-9b8f-35b5179c28fb&turn=7&action=4\r\n\tconst indexFromRight = heroPower.info2;\r\n\tconst rapidReanimationMinion = heroPower.info as BoardEntity;\r\n\tconst hasSummoned = handleSummon(\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tgameState,\r\n\t\trapidReanimationMinion.cardId,\r\n\t\tindexFromRight,\r\n\t\ttrue, // (Goldrinn gets buffed, so it seems we reapply auras? This is a mess tbh)\r\n\t\trapidReanimationMinion,\r\n\t);\r\n\tif (hasSummoned) {\r\n\t\theroPower.info = null;\r\n\t\t// Hard-coding a correction for Ancestral Automaton\r\n\t\t// Shold not be necessary if we reapply auras\r\n\t\t// hasSummoned.forEach((entity) => {\r\n\t\t// \tswitch (entity.cardId) {\r\n\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401:\r\n\t\t// \t\tcase CardIds.AstralAutomaton_BG_TTN_401_G:\r\n\t\t// \t\t\tconst overstatMult = entity.cardId === CardIds.AstralAutomaton_BG_TTN_401 ? 1 : 2;\r\n\t\t// \t\t\tentity.attack = Math.max(1, entity.attack + 2 * overstatMult);\r\n\t\t// \t\t\tentity.health = Math.max(0, entity.health + 2 * overstatMult);\r\n\t\t// \t\t\tbreak;\r\n\t\t// \t\tcase CardIds.EternalKnight_BG25_008:\r\n\t\t// \t\tcase CardIds.EternalKnight_BG25_008_G:\r\n\t\t// \t\t\tconst knightMult = entity.cardId === CardIds.EternalKnight_BG25_008 ? 1 : 2;\r\n\t\t// \t\t\tentity.attack = Math.max(1, entity.attack + 1 * knightMult);\r\n\t\t// \t\t\tentity.health = Math.max(0, entity.health + 1 * knightMult);\r\n\t\t// \t\t\tbreak;\r\n\t\t// \t}\r\n\t\t// });\r\n\t}\r\n\treturn false;\r\n};\r\n\r\nconst handleSummon = (\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n\tcardId: string,\r\n\tindexFromRight: number,\r\n\tapplyAuras: boolean,\r\n\tminion: BoardEntity = null,\r\n): readonly BoardEntity[] => {\r\n\tif (playerBoard.length >= 7) {\r\n\t\treturn null;\r\n\t}\r\n\tconst newMinion = buildSingleBoardEntity(\r\n\t\tcardId,\r\n\t\tplayerEntity,\r\n\t\tplayerBoard,\r\n\t\tgameState.allCards,\r\n\t\tplayerEntity.friendly,\r\n\t\tgameState.sharedState.currentEntityId++,\r\n\t\tfalse,\r\n\t\tgameState.cardsData,\r\n\t\tgameState.sharedState,\r\n\t\tminion,\r\n\t\tnull,\r\n\t);\r\n\t// Don't reapply auras in this particular case? See https://x.com/ZerotoHeroes_HS/status/1737422727118487808?s=20\r\n\tconst spawned = performEntitySpawns(\r\n\t\t[newMinion],\r\n\t\tplayerBoard,\r\n\t\tplayerEntity,\r\n\t\tplayerEntity,\r\n\t\tindexFromRight,\r\n\t\topponentBoard,\r\n\t\topponentEntity,\r\n\t\tgameState,\r\n\t\tapplyAuras,\r\n\t);\r\n\t// 2026-09-29: https://replays.firestoneapp.com/?reviewId=bced2a9c-cb41-4482-bb57-98e1a87970ef&turn=15&action=9\r\n\t// When the rapid reanimation target spawns to the left, it skips its turn if the left-most minion\r\n\t// had already attacked\r\n\tif (playerBoard.indexOf(newMinion) === 0) {\r\n\t\tnewMinion.hasAttacked = playerEntity.leftMostAttacked;\r\n\t}\r\n\tgameState.spectator.registerPowerTarget(playerEntity, newMinion, playerBoard, null, null);\r\n\treturn spawned;\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.762",
3
+ "version": "1.1.763",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "lint": "eslint --color --fix --ext .ts .",