@firestone-hs/simulate-bgs-battle 1.1.722 → 1.1.724
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cards/card.interface.d.ts +4 -0
- package/dist/cards/card.interface.js +4 -2
- package/dist/cards/card.interface.js.map +1 -1
- package/dist/cards/impl/_card-mappings.js +2 -0
- package/dist/cards/impl/_card-mappings.js.map +1 -1
- package/dist/cards/impl/hero-power/lightning-invocation.js +4 -1
- package/dist/cards/impl/hero-power/lightning-invocation.js.map +1 -1
- package/dist/cards/impl/minion/sneeds-new-shredder.js +1 -1
- package/dist/cards/impl/minion/sneeds-new-shredder.js.map +1 -1
- package/dist/cards/impl/minion/timewarped-embalmer.d.ts +2 -2
- package/dist/cards/impl/minion/timewarped-embalmer.js +5 -1
- package/dist/cards/impl/minion/timewarped-embalmer.js.map +1 -1
- package/dist/cards/impl/minion/timewarped-pagle.d.ts +2 -0
- package/dist/cards/impl/minion/timewarped-pagle.js +15 -0
- package/dist/cards/impl/minion/timewarped-pagle.js.map +1 -0
- package/dist/input-clone.d.ts +1 -0
- package/dist/input-clone.js +13 -1
- package/dist/input-clone.js.map +1 -1
- package/dist/mechanics/rally.js +14 -12
- package/dist/mechanics/rally.js.map +1 -1
- package/dist/mechanics/tavern-spell-repeat.js +3 -4
- package/dist/mechanics/tavern-spell-repeat.js.map +1 -1
- package/dist/simulate-bgs-battle.d.ts +1 -1
- package/dist/simulate-bgs-battle.js +80 -77
- package/dist/simulate-bgs-battle.js.map +1 -1
- package/dist/simulation/add-minion-to-board.d.ts +1 -1
- package/dist/simulation/add-minion-to-board.js +5 -2
- package/dist/simulation/add-minion-to-board.js.map +1 -1
- package/dist/simulation/attack.js +3 -3
- package/dist/simulation/attack.js.map +1 -1
- package/dist/simulation/avenge.js +2 -2
- package/dist/simulation/avenge.js.map +1 -1
- package/dist/simulation/deathrattle-effects.js +48 -14
- package/dist/simulation/deathrattle-effects.js.map +1 -1
- package/dist/simulation/deathrattle-spawns.js +19 -12
- package/dist/simulation/deathrattle-spawns.js.map +1 -1
- package/dist/simulation/deathrattle-utils.d.ts +1 -0
- package/dist/simulation/deathrattle-utils.js +45 -5
- package/dist/simulation/deathrattle-utils.js.map +1 -1
- package/dist/simulation/on-attack.js +13 -14
- package/dist/simulation/on-attack.js.map +1 -1
- package/dist/simulation/reborn.js +11 -0
- package/dist/simulation/reborn.js.map +1 -1
- package/dist/simulation/simulator.d.ts +1 -0
- package/dist/simulation/simulator.js +39 -74
- package/dist/simulation/simulator.js.map +1 -1
- package/dist/simulation/spectator/resolve-trinket-hero-power.js +11 -2
- package/dist/simulation/spectator/resolve-trinket-hero-power.js.map +1 -1
- package/dist/simulation/spectator/spectator.d.ts +4 -0
- package/dist/simulation/spectator/spectator.js +39 -19
- package/dist/simulation/spectator/spectator.js.map +1 -1
- package/dist/simulation/stats.js +95 -66
- package/dist/simulation/stats.js.map +1 -1
- package/dist/simulation/summon-when-space.js +24 -21
- package/dist/simulation/summon-when-space.js.map +1 -1
- package/dist/utils.js +89 -48
- package/dist/utils.js.map +1 -1
- package/package.json +3 -2
|
@@ -9,7 +9,10 @@ exports.LightningInvocation = {
|
|
|
9
9
|
for (const heroPower of input.playerEntity.heroPowers) {
|
|
10
10
|
if (exports.LightningInvocation.cardIds.includes(heroPower.cardId) && heroPower.used) {
|
|
11
11
|
(0, deathrattle_effects_1.applyLightningInvocationEnchantment)(input.playerBoard, input.playerEntity, input.playerEntity, input.opponentBoard, input.opponentEntity, input.gameState);
|
|
12
|
-
return
|
|
12
|
+
return {
|
|
13
|
+
hasTriggered: true,
|
|
14
|
+
shouldRecomputeCurrentAttacker: true,
|
|
15
|
+
};
|
|
13
16
|
}
|
|
14
17
|
}
|
|
15
18
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lightning-invocation.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/lightning-invocation.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"lightning-invocation.js","sourceRoot":"","sources":["../../../../src/cards/impl/hero-power/lightning-invocation.ts"],"names":[],"mappings":";;;AAIA,iFAA8F;AAIjF,QAAA,mBAAmB,GAAsB;IACrD,mBAAmB,EAAE,iBAAiB;IACtC,OAAO,EAAE,4CAA+D;IACxE,aAAa,EAAE,CAAC,OAAmE,EAAE,KAAe,EAAE,EAAE;QACvG,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE;YACtD,IAAI,2BAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE;gBAC7E,IAAA,yDAAmC,EAClC,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,aAAa,EACnB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CACf,CAAC;gBAGF,OAAO;oBACN,YAAY,EAAE,IAAI;oBAClB,8BAA8B,EAAE,IAAI;iBACpC,CAAC;aACF;SACD;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BgsPlayerEntity, BoardTrinket } from '../../../bgs-player-entity';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { BoardSecret } from '../../../board-secret';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { applyLightningInvocationEnchantment } from '../../../simulation/deathrattle-effects';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const LightningInvocation: StartOfCombatCard = {\r\n\tstartOfCombatTiming: 'start-of-combat',\r\n\tcardIds: [CardIds.LightningInvocationToken, CardIds.LightningInvocation],\r\n\tstartOfCombat: (trinket: BoardTrinket | BoardEntity | BgsPlayerEntity | BoardSecret, input: SoCInput) => {\r\n\t\tfor (const heroPower of input.playerEntity.heroPowers) {\r\n\t\t\tif (LightningInvocation.cardIds.includes(heroPower.cardId) && heroPower.used) {\r\n\t\t\t\tapplyLightningInvocationEnchantment(\r\n\t\t\t\t\tinput.playerBoard,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\tinput.opponentBoard,\r\n\t\t\t\t\tinput.opponentEntity,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t);\r\n\t\t\t\t// See https://replays.firestoneapp.com/?reviewId=09b7ace7-cbe1-4533-bf58-c26d04fa15e9&turn=11&action=8\r\n\t\t\t\t// 2 vs 4 minions, and the 2 side attacks after it becoems 2 vs 2\r\n\t\t\t\treturn {\r\n\t\t\t\t\thasTriggered: true,\r\n\t\t\t\t\tshouldRecomputeCurrentAttacker: true,\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
|
@@ -25,7 +25,7 @@ exports.SneedsNewShredder = {
|
|
|
25
25
|
if (spawn) {
|
|
26
26
|
spawn.locked = true;
|
|
27
27
|
const copy = { ...spawn };
|
|
28
|
-
(0, add_minion_to_board_1.removeAurasFromSelf)(copy, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.gameState);
|
|
28
|
+
(0, add_minion_to_board_1.removeAurasFromSelf)(copy, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.gameState, true, true, false);
|
|
29
29
|
const spawns = (0, deathrattle_spawns_1.spawnEntities)(spawn.cardId, 1, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.otherBoard, input.otherBoardHero, input.gameState, minion.friendly, false, false, true, copy);
|
|
30
30
|
for (const s of spawns) {
|
|
31
31
|
(0, divine_shield_1.updateDivineShield)(s, input.boardWithDeadEntity, input.boardWithDeadEntityHero, input.otherBoardHero, true, input.gameState);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sneeds-new-shredder.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/sneeds-new-shredder.ts"],"names":[],"mappings":";;;AACA,mEAAqE;AAErE,mDAAqD;AACrD,iFAA8E;AAE9E,+EAAuE;AAG1D,QAAA,iBAAiB,GAAyB;IACtD,OAAO,EAAE,sCAAiG;IAC1G,gBAAgB,EAAE,CAAC,MAAmB,EAAE,KAAgC,EAAE,EAAE;;QAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,uBAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClF,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE;YAC9B,MAAM,IAAI,GACT,MAAA,KAAK,CAAC,uBAAuB,CAAC,IAAI;iBAChC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC;iBAG1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,mCAAI,EAAE,CAAC;YAClC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACrF,MAAM,oBAAoB,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACnG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAA,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,MAAM,CAAA;gBAC3C,CAAC,CAAC,IAAA,kBAAU,EAAC,oBAAoB,CAAC;gBAClC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM;oBACrC,CAAC,CAAC,IAAA,kBAAU,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBAC1C,CAAC,CAAC,IAAI,CAAC;YACR,IAAI,KAAK,EAAE;gBAEV,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;gBACpB,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAiB,CAAC;gBACzC,IAAA,yCAAmB,
|
|
1
|
+
{"version":3,"file":"sneeds-new-shredder.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/sneeds-new-shredder.ts"],"names":[],"mappings":"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","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { updateDivineShield } from '../../../keywords/divine-shield';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { pickRandom } from '../../../services/utils';\r\nimport { removeAurasFromSelf } from '../../../simulation/add-minion-to-board';\r\nimport { DeathrattleTriggeredInput } from '../../../simulation/deathrattle-on-trigger';\r\nimport { spawnEntities } from '../../../simulation/deathrattle-spawns';\r\nimport { DeathrattleSpawnCard } from '../../card.interface';\r\n\r\nexport const SneedsNewShredder: DeathrattleSpawnCard = {\r\n\tcardIds: [CardIds.Sneed_SneedsNewShredderToken_BG21_HERO_030t, CardIds.SneedsNewShredder_BG21_HERO_030t_G],\r\n\tdeathrattleSpawn: (minion: BoardEntity, input: DeathrattleTriggeredInput) => {\r\n\t\tconst mult = minion.cardId === CardIds.SneedsNewShredder_BG21_HERO_030t_G ? 2 : 1;\r\n\t\tconst allSpawns = [];\r\n\t\tfor (let i = 0; i < mult; i++) {\r\n\t\t\tconst hand =\r\n\t\t\t\tinput.boardWithDeadEntityHero.hand\r\n\t\t\t\t\t.filter((e) => !!e?.cardId)\r\n\t\t\t\t\t// 2025-12-04: it can summon a minion that is locked by another way, like Flighty scout\r\n\t\t\t\t\t// BUT: if it was summoned by Bassgill, then it won't work\r\n\t\t\t\t\t.filter((e) => !e.locked) ?? [];\r\n\t\t\tconst highestHealth = Math.max(...hand.filter((c) => c.health).map((c) => c.health));\r\n\t\t\tconst highestHealthMinions = highestHealth ? hand.filter((c) => c.health === highestHealth) : null;\r\n\t\t\tconst spawn = !!highestHealthMinions?.length\r\n\t\t\t\t? pickRandom(highestHealthMinions)\r\n\t\t\t\t: hand.filter((c) => c.cardId).length\r\n\t\t\t\t? pickRandom(hand.filter((c) => c.cardId))\r\n\t\t\t\t: null;\r\n\t\t\tif (spawn) {\r\n\t\t\t\t// 2025-12-04: actually doesn't look like it gets locked\r\n\t\t\t\tspawn.locked = true;\r\n\t\t\t\tconst copy = { ...spawn } as BoardEntity;\r\n\t\t\t\tremoveAurasFromSelf(\r\n\t\t\t\t\tcopy,\r\n\t\t\t\t\tinput.boardWithDeadEntity,\r\n\t\t\t\t\tinput.boardWithDeadEntityHero,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t);\r\n\t\t\t\tconst spawns = spawnEntities(\r\n\t\t\t\t\tspawn.cardId,\r\n\t\t\t\t\t1,\r\n\t\t\t\t\tinput.boardWithDeadEntity,\r\n\t\t\t\t\tinput.boardWithDeadEntityHero,\r\n\t\t\t\t\tinput.otherBoard,\r\n\t\t\t\t\tinput.otherBoardHero,\r\n\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\tminion.friendly,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\tfalse,\r\n\t\t\t\t\ttrue,\r\n\t\t\t\t\tcopy,\r\n\t\t\t\t);\r\n\t\t\t\tfor (const s of spawns) {\r\n\t\t\t\t\tupdateDivineShield(\r\n\t\t\t\t\t\ts,\r\n\t\t\t\t\t\tinput.boardWithDeadEntity,\r\n\t\t\t\t\t\tinput.boardWithDeadEntityHero,\r\n\t\t\t\t\t\tinput.otherBoardHero,\r\n\t\t\t\t\t\ttrue,\r\n\t\t\t\t\t\tinput.gameState,\r\n\t\t\t\t\t);\r\n\t\t\t\t\ts.onCanceledSummon = () => (spawn.locked = false);\r\n\t\t\t\t\t// s.backRef = spawn;\r\n\t\t\t\t}\r\n\t\t\t\tallSpawns.push(...spawns);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn allSpawns;\r\n\t},\r\n};\r\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DefaultChargesCard, OnOtherSpawnedCard } from '../../card.interface';
|
|
2
|
-
export declare const TimewarpedEmbalmer: OnOtherSpawnedCard & DefaultChargesCard;
|
|
1
|
+
import { BeforeRebornSelfEffectCard, DefaultChargesCard, OnOtherSpawnedCard } from '../../card.interface';
|
|
2
|
+
export declare const TimewarpedEmbalmer: OnOtherSpawnedCard & DefaultChargesCard & BeforeRebornSelfEffectCard;
|
|
@@ -6,11 +6,15 @@ exports.TimewarpedEmbalmer = {
|
|
|
6
6
|
cardIds: ["BG34_Giant_332", "BG34_Giant_332_G"],
|
|
7
7
|
defaultCharges: (entity) => entity.scriptDataNum1,
|
|
8
8
|
onOtherSpawned: (minion, input) => {
|
|
9
|
-
if (minion.abiityChargesLeft > 0) {
|
|
9
|
+
if (minion.abiityChargesLeft > 0 && !input.spawned.reborn) {
|
|
10
10
|
minion.abiityChargesLeft--;
|
|
11
11
|
const target = input.spawned;
|
|
12
12
|
(0, reborn_1.updateReborn)(target, true, input.board, input.hero, input.otherHero, input.gameState);
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
+
beforeRebornSelfEffect: (minion, input) => {
|
|
16
|
+
minion.scriptDataNum1 = 2;
|
|
17
|
+
minion.abiityChargesLeft = 2;
|
|
18
|
+
},
|
|
15
19
|
};
|
|
16
20
|
//# sourceMappingURL=timewarped-embalmer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timewarped-embalmer.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-embalmer.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"timewarped-embalmer.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-embalmer.ts"],"names":[],"mappings":";;;AAEA,qDAAwD;AAM3C,QAAA,kBAAkB,GAAyE;IACvG,OAAO,EAAE,sCAAwF;IAEjG,cAAc,EAAE,CAAC,MAAmB,EAAE,EAAE,CAEvC,MAAM,CAAC,cAAc;IACtB,cAAc,EAAE,CAAC,MAAkC,EAAE,KAAwB,EAAE,EAAE;QAChF,IAAK,MAAsB,CAAC,iBAAiB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE;YAC1E,MAAsB,CAAC,iBAAiB,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;YAC7B,IAAA,qBAAY,EAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;SACtF;IACF,CAAC;IACD,sBAAsB,EAAE,CAAC,MAAkC,EAAE,KAAwB,EAAE,EAAE;QACvF,MAAsB,CAAC,cAAc,GAAG,CAAC,CAAC;QAC1C,MAAsB,CAAC,iBAAiB,GAAG,CAAC,CAAC;IAC/C,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { updateReborn } from '../../../keywords/reborn';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { OnOtherSpawnInput } from '../../../simulation/add-minion-to-board';\r\nimport { RebornEffectInput } from '../../../simulation/reborn';\r\nimport { BeforeRebornSelfEffectCard, DefaultChargesCard, OnOtherSpawnedCard } from '../../card.interface';\r\n\r\nexport const TimewarpedEmbalmer: OnOtherSpawnedCard & DefaultChargesCard & BeforeRebornSelfEffectCard = {\r\n\tcardIds: [CardIds.TimewarpedEmbalmer_BG34_Giant_332, CardIds.TimewarpedEmbalmer_BG34_Giant_332_G],\r\n\t// It only resets at the start of the shop phase, so we need to rely on the value from the board state\r\n\tdefaultCharges: (entity: BoardEntity) =>\r\n\t\t// Some charges can be used during the shop phase\r\n\t\tentity.scriptDataNum1,\r\n\tonOtherSpawned: (minion: BoardEntity | BoardTrinket, input: OnOtherSpawnInput) => {\r\n\t\tif ((minion as BoardEntity).abiityChargesLeft > 0 && !input.spawned.reborn) {\r\n\t\t\t(minion as BoardEntity).abiityChargesLeft--;\r\n\t\t\tconst target = input.spawned;\r\n\t\t\tupdateReborn(target, true, input.board, input.hero, input.otherHero, input.gameState);\r\n\t\t}\r\n\t},\r\n\tbeforeRebornSelfEffect: (minion: BoardEntity | BoardTrinket, input: RebornEffectInput) => {\r\n\t\t(minion as BoardEntity).scriptDataNum1 = 2;\r\n\t\t(minion as BoardEntity).abiityChargesLeft = 2;\r\n\t},\r\n};\r\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TimewarpedPagle = void 0;
|
|
4
|
+
const cards_in_hand_1 = require("../../../simulation/cards-in-hand");
|
|
5
|
+
exports.TimewarpedPagle = {
|
|
6
|
+
cardIds: ["BG34_Giant_208", "BG34_Giant_208_G"],
|
|
7
|
+
onMinionKilled: (_entity, input) => {
|
|
8
|
+
if (input.killer !== _entity || !input.killerIsAttacking) {
|
|
9
|
+
return { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };
|
|
10
|
+
}
|
|
11
|
+
(0, cards_in_hand_1.addCardsInHand)(input.attackingHero, input.attackingBoard, ["TB_BaconShop_Triples_01"], input.gameState);
|
|
12
|
+
return { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=timewarped-pagle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timewarped-pagle.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-pagle.ts"],"names":[],"mappings":";;;AAGA,qEAAmE;AAGtD,QAAA,eAAe,GAAuB;IAClD,OAAO,EAAE,sCAAkF;IAC3F,cAAc,EAAE,CAAC,OAAoB,EAAE,KAA0B,EAAE,EAAE;QACpE,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE;YACzD,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;SACtD;QACD,IAAA,8BAAc,EAAC,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,cAAc,EAAE,2BAAsB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACnG,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { OnMinionKilledInput } from '../../../simulation/attack';\r\nimport { addCardsInHand } from '../../../simulation/cards-in-hand';\r\nimport { OnMinionKilledCard } from '../../card.interface';\r\n\r\nexport const TimewarpedPagle: OnMinionKilledCard = {\r\n\tcardIds: [CardIds.TimewarpedPagle_BG34_Giant_208, CardIds.TimewarpedPagle_BG34_Giant_208_G],\r\n\tonMinionKilled: (_entity: BoardEntity, input: OnMinionKilledInput) => {\r\n\t\tif (input.killer !== _entity || !input.killerIsAttacking) {\r\n\t\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t\t}\r\n\t\taddCardsInHand(input.attackingHero, input.attackingBoard, [CardIds.TripleReward], input.gameState);\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n};\r\n"]}
|
package/dist/input-clone.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BgsBattleInfo } from './bgs-battle-info';
|
|
2
2
|
import { BgsBoardInfo } from './bgs-board-info';
|
|
3
|
+
export declare const buildTemplateCloner: (template: BgsBattleInfo) => (() => BgsBattleInfo);
|
|
3
4
|
export declare const cloneInput3: (input: BgsBattleInfo) => BgsBattleInfo;
|
|
4
5
|
export declare const cloneBoard: (board: BgsBoardInfo) => BgsBoardInfo;
|
package/dist/input-clone.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.cloneBoard = exports.cloneInput3 = void 0;
|
|
3
|
+
exports.cloneBoard = exports.cloneInput3 = exports.buildTemplateCloner = void 0;
|
|
4
|
+
const buildTemplateCloner = (template) => {
|
|
5
|
+
const str = JSON.stringify(template);
|
|
6
|
+
if (!str.includes('"__proto__"')) {
|
|
7
|
+
try {
|
|
8
|
+
return new Function(`return ${str};`);
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return () => JSON.parse(str);
|
|
14
|
+
};
|
|
15
|
+
exports.buildTemplateCloner = buildTemplateCloner;
|
|
4
16
|
const cloneInput3 = (input) => {
|
|
5
17
|
const result = {
|
|
6
18
|
gameState: {
|
package/dist/input-clone.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-clone.js","sourceRoot":"","sources":["../src/input-clone.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"input-clone.js","sourceRoot":"","sources":["../src/input-clone.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BgsBoardInfo } from './bgs-board-info';\r\nimport { BoardEntity } from './board-entity';\r\n\r\n// const cloneInput = (input: BgsBattleInfo): BgsBattleInfo => {\r\n// \treturn structuredClone(input);\r\n// };\r\n// const cloneInput2 = (input: string): BgsBattleInfo => {\r\n// \treturn JSON.parse(input);\r\n// };\r\n\r\n/**\r\n * Builds a function that returns a fresh deep copy of the template on every call.\r\n *\r\n * The template is serialized once, and compiled into a function body that rebuilds it as a\r\n * plain object literal. V8 parses that literal a single time, so each subsequent call only\r\n * allocates the objects, which is much faster than re-parsing JSON on every simulation\r\n * iteration (measured ~0.02ms/clone vs ~0.12ms for JSON.parse on a 7v7 board).\r\n */\r\nexport const buildTemplateCloner = (template: BgsBattleInfo): (() => BgsBattleInfo) => {\r\n\tconst str = JSON.stringify(template);\r\n\t// In an object literal (unlike JSON.parse), a \"__proto__\" key would set the prototype\r\n\t// instead of creating an own property. Our input shape never contains that key, but if\r\n\t// it ever does, fall back to the safe path\r\n\tif (!str.includes('\"__proto__\"')) {\r\n\t\ttry {\r\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-implied-eval\r\n\t\t\treturn new Function(`return ${str};`) as () => BgsBattleInfo;\r\n\t\t} catch (e) {\r\n\t\t\t// Code generation from strings can be disallowed (e.g. by a CSP when this runs\r\n\t\t\t// inside the app); JSON.parse is the fallback\r\n\t\t}\r\n\t}\r\n\treturn () => JSON.parse(str);\r\n};\r\n\r\nexport const cloneInput3 = (input: BgsBattleInfo): BgsBattleInfo => {\r\n\tconst result: BgsBattleInfo = {\r\n\t\tgameState: {\r\n\t\t\tcurrentTurn: input.gameState.currentTurn,\r\n\t\t\tanomalies: input.gameState.anomalies,\r\n\t\t\tvalidTribes: input.gameState.validTribes,\r\n\t\t},\r\n\t\theroHasDied: input.heroHasDied,\r\n\t\tplayerBoard: cloneBoard(input.playerBoard),\r\n\t\topponentBoard: cloneBoard(input.opponentBoard),\r\n\t\tplayerTeammateBoard: cloneBoard(input.playerTeammateBoard),\r\n\t\topponentTeammateBoard: cloneBoard(input.opponentTeammateBoard),\r\n\t\toptions: null,\r\n\t};\r\n\treturn result;\r\n};\r\n\r\nexport const cloneBoard = (board: BgsBoardInfo): BgsBoardInfo => {\r\n\tif (!board) {\r\n\t\treturn null;\r\n\t}\r\n\tconst result: BgsBoardInfo = {\r\n\t\tplayer: {\r\n\t\t\t...board.player,\r\n\t\t\tquestEntities: board.player.questEntities?.map((quest) => ({ ...quest })),\r\n\t\t\tquestRewardEntities: board.player.questRewardEntities?.map((reward) => ({ ...reward })),\r\n\t\t\tquestRewards: board.player.questRewards?.map((reward) => reward),\r\n\t\t\thand: board.player.hand?.map((entity) => cloneEntity(entity)),\r\n\t\t\tsecrets: board.player.secrets?.map((secret) => ({ ...secret })).sort((a, b) => a.entityId - b.entityId),\r\n\t\t\ttrinkets: board.player.trinkets?.map((trinket) => ({ ...trinket, tags: { ...trinket.tags } })),\r\n\t\t\tglobalInfo: { ...board.player.globalInfo },\r\n\t\t\theroPowers: board.player.heroPowers?.map((heroPower) => ({ ...heroPower })),\r\n\t\t},\r\n\t\tboard: board.board.map((entity) => cloneEntity(entity)),\r\n\t};\r\n\treturn result;\r\n};\r\n\r\nconst cloneEntity = (entity: BoardEntity): BoardEntity => {\r\n\tconst result: BoardEntity = {\r\n\t\t...entity,\r\n\t\tenchantments: entity.enchantments.map((enchant) => ({ ...enchant })),\r\n\t\tpendingAttackBuffs: [],\r\n\t\tadditionalCards: entity.additionalCards?.map((card) => card),\r\n\t\trememberedDeathrattles: [],\r\n\t};\r\n\treturn result;\r\n};\r\n"]}
|
package/dist/mechanics/rally.js
CHANGED
|
@@ -13,18 +13,20 @@ const triggerRally = (attackingBoard, attackingBoardHero, attacker, defendingBoa
|
|
|
13
13
|
let damageDoneByAttacker = 0;
|
|
14
14
|
let damageDoneByDefender = 0;
|
|
15
15
|
const isAttackerRallying = (0, utils_1.hasEntityMechanic)(attacker, reference_data_1.GameTag.BACON_RALLY, gameState.allCards);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
?
|
|
24
|
-
:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
let rallyLoops = 1;
|
|
17
|
+
if (isAttackerRallying) {
|
|
18
|
+
const cardIds = [
|
|
19
|
+
...attackingBoard.map((e) => e.cardId),
|
|
20
|
+
...((_b = (_a = attackingBoardHero.secrets) === null || _a === void 0 ? void 0 : _a.map((e) => e.cardId)) !== null && _b !== void 0 ? _b : []),
|
|
21
|
+
];
|
|
22
|
+
const triggerMult = cardIds.some((cardId) => TRIPLE_RALLY_CARD_IDS.includes(cardId))
|
|
23
|
+
? 3
|
|
24
|
+
: cardIds.some((cardId) => DOUBLE_RALLY_CARD_IDS.includes(cardId))
|
|
25
|
+
? 2
|
|
26
|
+
: 1;
|
|
27
|
+
const numberOfRallyingCries = (_d = (_c = attackingBoardHero.questRewardEntities) === null || _c === void 0 ? void 0 : _c.filter((r) => r.cardId === "BG33_Reward_021").length) !== null && _d !== void 0 ? _d : 0;
|
|
28
|
+
rallyLoops = triggerMult + numberOfRallyingCries;
|
|
29
|
+
}
|
|
28
30
|
for (let i = 0; i < rallyLoops; i++) {
|
|
29
31
|
const onAttackImpl = _card_mappings_1.cardMappings[attacker.cardId];
|
|
30
32
|
if ((0, card_interface_1.hasRally)(onAttackImpl)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rally.js","sourceRoot":"","sources":["../../src/mechanics/rally.ts"],"names":[],"mappings":";;;AAAA,iEAAuD;AAGvD,4DAAmD;AACnD,iEAA4D;AAE5D,6DAA6D;AAE7D,oCAA6C;AAE7C,MAAM,qBAAqB,GAAa,kBAAwC,CAAC;AACjF,MAAM,qBAAqB,GAAa,oBAA0C,CAAC;AAE5E,MAAM,YAAY,GAAG,CAC3B,cAA6B,EAC7B,kBAAmC,EACnC,QAAqB,EACrB,cAA6B,EAC7B,kBAAmC,EACnC,eAA4B,EAC5B,SAAwB,EACmC,EAAE;;IAC7D,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,MAAM,kBAAkB,GAAG,IAAA,yBAAiB,EAAC,QAAQ,EAAE,wBAAO,CAAC,WAAW,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"rally.js","sourceRoot":"","sources":["../../src/mechanics/rally.ts"],"names":[],"mappings":"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","sourcesContent":["import { GameTag } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasRally } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { fixEnchantments } from '../simulation/enchantments';\r\nimport { FullGameState } from '../simulation/internal-game-state';\r\nimport { hasEntityMechanic } from '../utils';\r\n\r\nconst DOUBLE_RALLY_CARD_IDS: string[] = [CardIds.TimewarpedDeios_BG34_Giant_376];\r\nconst TRIPLE_RALLY_CARD_IDS: string[] = [CardIds.TimewarpedDeios_BG34_Giant_376_G];\r\n\r\nexport const triggerRally = (\r\n\tattackingBoard: BoardEntity[],\r\n\tattackingBoardHero: BgsPlayerEntity,\r\n\tattacker: BoardEntity,\r\n\tdefendingBoard: BoardEntity[],\r\n\tdefendingBoardHero: BgsPlayerEntity,\r\n\tdefendingEntity: BoardEntity,\r\n\tgameState: FullGameState,\r\n): { dmgDoneByAttacker: number; dmgDoneByDefender: number } => {\r\n\tlet damageDoneByAttacker = 0;\r\n\tlet damageDoneByDefender = 0;\r\n\tconst isAttackerRallying = hasEntityMechanic(attacker, GameTag.BACON_RALLY, gameState.allCards);\r\n\r\n\t// Only compute the multiplier when the attacker actually rallies, as this is a hot path\r\n\tlet rallyLoops = 1;\r\n\tif (isAttackerRallying) {\r\n\t\tconst cardIds = [\r\n\t\t\t...attackingBoard.map((e) => e.cardId),\r\n\t\t\t...(attackingBoardHero.secrets?.map((e) => e.cardId) ?? []),\r\n\t\t];\r\n\t\tconst triggerMult = cardIds.some((cardId) => TRIPLE_RALLY_CARD_IDS.includes(cardId))\r\n\t\t\t? 3\r\n\t\t\t: cardIds.some((cardId) => DOUBLE_RALLY_CARD_IDS.includes(cardId))\r\n\t\t\t? 2\r\n\t\t\t: 1;\r\n\t\tconst numberOfRallyingCries =\r\n\t\t\tattackingBoardHero.questRewardEntities?.filter((r) => r.cardId === CardIds.RallyingCry_BG33_Reward_021)\r\n\t\t\t\t.length ?? 0;\r\n\t\trallyLoops = triggerMult + numberOfRallyingCries;\r\n\t}\r\n\r\n\tfor (let i = 0; i < rallyLoops; i++) {\r\n\t\tconst onAttackImpl = cardMappings[attacker.cardId];\r\n\t\tif (hasRally(onAttackImpl)) {\r\n\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onAttackImpl.rally(attacker, {\r\n\t\t\t\tattacker: attacker,\r\n\t\t\t\tattackingHero: attackingBoardHero,\r\n\t\t\t\tattackingBoard: attackingBoard,\r\n\t\t\t\tdefendingEntity: defendingEntity,\r\n\t\t\t\tdefendingHero: defendingBoardHero,\r\n\t\t\t\tdefendingBoard: defendingBoard,\r\n\t\t\t\tgameState,\r\n\t\t\t\tplayerIsFriendly: attackingBoardHero.friendly,\r\n\t\t\t});\r\n\t\t\tdamageDoneByAttacker += dmgDoneByAttacker;\r\n\t\t\tdamageDoneByDefender += dmgDoneByDefender;\r\n\t\t}\r\n\t\tconst enchantments = attacker.enchantments;\r\n\t\tfor (const enchantment of enchantments) {\r\n\t\t\tconst onAttackImpl = cardMappings[enchantment.cardId];\r\n\t\t\tif (hasRally(onAttackImpl)) {\r\n\t\t\t\tlet enchantmentToMinion: BoardEntity = {\r\n\t\t\t\t\t...enchantment,\r\n\t\t\t\t\tentityId: attacker.entityId,\r\n\t\t\t\t\tattack: attacker.attack,\r\n\t\t\t\t\thealth: attacker.health,\r\n\t\t\t\t\tmaxHealth: attacker.maxHealth,\r\n\t\t\t\t\tmaxAttack: attacker.maxAttack,\r\n\t\t\t\t\tabiityChargesLeft: attacker.abiityChargesLeft,\r\n\t\t\t\t};\r\n\t\t\t\tenchantmentToMinion = fixEnchantments(enchantmentToMinion, gameState.allCards);\r\n\t\t\t\tconst { dmgDoneByAttacker, dmgDoneByDefender } = onAttackImpl.rally(enchantmentToMinion, {\r\n\t\t\t\t\tattacker: attacker,\r\n\t\t\t\t\tattackingHero: attackingBoardHero,\r\n\t\t\t\t\tattackingBoard: attackingBoard,\r\n\t\t\t\t\tdefendingEntity: defendingEntity,\r\n\t\t\t\t\tdefendingHero: defendingBoardHero,\r\n\t\t\t\t\tdefendingBoard: defendingBoard,\r\n\t\t\t\t\tgameState,\r\n\t\t\t\t\tplayerIsFriendly: attackingBoardHero.friendly,\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\treturn { dmgDoneByAttacker: damageDoneByAttacker, dmgDoneByDefender: damageDoneByDefender };\r\n};\r\n"]}
|
|
@@ -26,15 +26,14 @@ const getTavernSpellEffectRepeatCount = (input) => {
|
|
|
26
26
|
repeats += proudPrivateerExtra;
|
|
27
27
|
}
|
|
28
28
|
const cathedrals = input.hero.trinkets.filter((t) => {
|
|
29
|
-
var _a
|
|
29
|
+
var _a;
|
|
30
30
|
return t.cardId === "BG30_MagicItem_434" &&
|
|
31
|
-
t.
|
|
32
|
-
((_b = (_a = t.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.TRIGGER_VISUAL]) !== null && _b !== void 0 ? _b : 0) > 0;
|
|
31
|
+
!((_a = t.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.TAG_SCRIPT_DATA_NUM_6]);
|
|
33
32
|
});
|
|
34
33
|
repeats += cathedrals.length;
|
|
35
34
|
for (const cathedral of cathedrals) {
|
|
36
35
|
cathedral.tags = (_b = cathedral.tags) !== null && _b !== void 0 ? _b : {};
|
|
37
|
-
cathedral.tags[reference_data_1.GameTag.
|
|
36
|
+
cathedral.tags[reference_data_1.GameTag.TAG_SCRIPT_DATA_NUM_6] = 1;
|
|
38
37
|
}
|
|
39
38
|
return repeats;
|
|
40
39
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tavern-spell-repeat.js","sourceRoot":"","sources":["../../src/mechanics/tavern-spell-repeat.ts"],"names":[],"mappings":";;;AAAA,iEAAuD;AAQhD,MAAM,+BAA+B,GAAG,CAAC,KAAqB,EAAU,EAAE;;IAChF,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE;QAChC,OAAO,CAAC,CAAC;KACT;IACD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAA0C,CAAC,CAAC;IACrG,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAwC,CAAC,CAAC;IACnG,IACC,CAAC,gBAAgB,IAAI,gBAAgB,CAAC;QACtC,KAAK,CAAC,MAAM;QACZ,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC5D;QACD,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACnC;IACD,MAAM,cAAc,GACnB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAuC,CAAC,CAAC,MAAM;QACjF,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAAyC,CAAC,CAAC,MAAM,CAAC;IACzF,OAAO,IAAI,cAAc,CAAC;IAE1B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACtE,MAAM,aAAa,GAAG,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,SAAS,0CAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAErE,IAAI,aAAa,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE;QACjD,MAAM,mBAAmB,GACxB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAoC,CAAC,CAAC,MAAM;YAC9E,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAAsC,CAAC,CAAC,MAAM,CAAC;QACtF,OAAO,IAAI,mBAAmB,CAAC;KAC/B;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAC5C,CAAC,CAAC,EAAE,EAAE;;QACL,OAAA,CAAC,CAAC,MAAM,yBAAgD;
|
|
1
|
+
{"version":3,"file":"tavern-spell-repeat.js","sourceRoot":"","sources":["../../src/mechanics/tavern-spell-repeat.ts"],"names":[],"mappings":";;;AAAA,iEAAuD;AAQhD,MAAM,+BAA+B,GAAG,CAAC,KAAqB,EAAU,EAAE;;IAChF,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE;QAChC,OAAO,CAAC,CAAC;KACT;IACD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAA0C,CAAC,CAAC;IACrG,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAwC,CAAC,CAAC;IACnG,IACC,CAAC,gBAAgB,IAAI,gBAAgB,CAAC;QACtC,KAAK,CAAC,MAAM;QACZ,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC5D;QACD,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACnC;IACD,MAAM,cAAc,GACnB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAuC,CAAC,CAAC,MAAM;QACjF,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAAyC,CAAC,CAAC,MAAM,CAAC;IACzF,OAAO,IAAI,cAAc,CAAC;IAE1B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACtE,MAAM,aAAa,GAAG,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,SAAS,0CAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAErE,IAAI,aAAa,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,EAAE;QACjD,MAAM,mBAAmB,GACxB,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAoC,CAAC,CAAC,MAAM;YAC9E,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAAsC,CAAC,CAAC,MAAM,CAAC;QACtF,OAAO,IAAI,mBAAmB,CAAC;KAC/B;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAC5C,CAAC,CAAC,EAAE,EAAE;;QACL,OAAA,CAAC,CAAC,MAAM,yBAAgD;YAexD,CAAC,CAAA,MAAA,CAAC,CAAC,IAAI,0CAAG,wBAAO,CAAC,qBAAqB,CAAC,CAAA,CAAA;KAAA,CACzC,CAAC;IACF,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC;IAC7B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;QACnC,SAAS,CAAC,IAAI,GAAG,MAAA,SAAS,CAAC,IAAI,mCAAI,EAAE,CAAC;QACtC,SAAS,CAAC,IAAI,CAAC,wBAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;KAClD;IAED,OAAO,OAAO,CAAC;AAChB,CAAC,CAAC;AAvDW,QAAA,+BAA+B,mCAuD1C","sourcesContent":["import { GameTag } from '@firestone-hs/reference-data';\r\nimport { CastSpellInput } from '../cards/card.interface';\r\nimport { CardIds } from '../services/card-ids';\r\n\r\n/**\r\n * Balinda Stonehearth: extra spell effect resolutions for spells you cast that target a friendly board minion.\r\n * Maelstrom Emergent: each copy adds +1 extra resolution (golden +2) for tavern spells you cast; stacks additively with Balinda.\r\n */\r\nexport const getTavernSpellEffectRepeatCount = (input: CastSpellInput): number => {\r\n\tif (input.source !== input.hero) {\r\n\t\treturn 1;\r\n\t}\r\n\tlet repeats = 1;\r\n\tconst hasGoldenBalinda = input.board.some((e) => e.cardId === CardIds.BalindaStonehearth_BG35_883_G);\r\n\tconst hasNormalBalinda = input.board.some((e) => e.cardId === CardIds.BalindaStonehearth_BG35_883);\r\n\tif (\r\n\t\t(hasGoldenBalinda || hasNormalBalinda) &&\r\n\t\tinput.target &&\r\n\t\tinput.board.some((e) => e.entityId === input.target.entityId)\r\n\t) {\r\n\t\trepeats = hasGoldenBalinda ? 3 : 2;\r\n\t}\r\n\tconst maelstromExtra =\r\n\t\tinput.board.filter((e) => e.cardId === CardIds.MaelstromEmergent_BG34_922).length +\r\n\t\t2 * input.board.filter((e) => e.cardId === CardIds.MaelstromEmergent_BG34_922_G).length;\r\n\trepeats += maelstromExtra;\r\n\r\n\tconst spellCard = input.gameState.allCards.getCard(input.spellCardId);\r\n\tconst isBountySpell = spellCard?.mechanics?.includes('BACON_BOUNTY');\r\n\t// Proud Privateer only affects bounties *you* (the hero) cast — same as Balinda / onTavernSpellCast.\r\n\tif (isBountySpell && input.source === input.hero) {\r\n\t\tconst proudPrivateerExtra =\r\n\t\t\tinput.board.filter((e) => e.cardId === CardIds.ProudPrivateer_BG33_825).length +\r\n\t\t\t2 * input.board.filter((e) => e.cardId === CardIds.ProudPrivateer_BG33_825_G).length;\r\n\t\trepeats += proudPrivateerExtra;\r\n\t}\r\n\r\n\tconst cathedrals = input.hero.trinkets.filter(\r\n\t\t(t) =>\r\n\t\t\tt.cardId === CardIds.ReplicaCathedral_BG30_MagicItem_434 &&\r\n\t\t\t// 2026-04-25:https://replays.firestoneapp.com/?reviewId=f7d1d5ec-b83d-49f5-9669-b063a3debc79&turn=15&action=1\r\n\t\t\t// It triggered during shop, and doesn't re-trigger during combat\r\n\t\t\t/**\r\n\t\t\t * \t{\r\n\t\t\t\t\t\"cardId\": \"BG30_MagicItem_434\",\r\n\t\t\t\t\t\"entityId\": 306,\r\n\t\t\t\t\t\"scriptDataNum1\": 1,\r\n\t\t\t\t\t\"scriptDataNum2\": 0,\r\n\t\t\t\t\t\"scriptDataNum6\": 1\r\n\t\t\t\t},\r\n\t\t\t */\r\n\t\t\t// 2026-07-22: This is not relevant. I had the case where TRIGGER_VISUAL was 1 but it wouln't re-trigger\r\n\t\t\t// (t.tags?.[GameTag.TRIGGER_VISUAL] ?? 0) > 0,\r\n\t\t\t// Next try is SCRIPT_DATA_NUM_6, assuming 1 meaning it can't trigger\r\n\t\t\t!t.tags?.[GameTag.TAG_SCRIPT_DATA_NUM_6],\r\n\t);\r\n\trepeats += cathedrals.length;\r\n\tfor (const cathedral of cathedrals) {\r\n\t\tcathedral.tags = cathedral.tags ?? {};\r\n\t\tcathedral.tags[GameTag.TAG_SCRIPT_DATA_NUM_6] = 1;\r\n\t}\r\n\r\n\treturn repeats;\r\n};\r\n"]}
|
|
@@ -2,8 +2,8 @@ import { AllCardsService } from '@firestone-hs/reference-data';
|
|
|
2
2
|
import { BgsBattleInfo } from './bgs-battle-info';
|
|
3
3
|
import { CardsData } from './cards/cards-data';
|
|
4
4
|
import { SimulationResult } from './simulation-result';
|
|
5
|
+
export { isValidDeathrattleEnchantment } from './simulation/deathrattle-utils';
|
|
5
6
|
export declare const assignCards: (cards: AllCardsService) => void;
|
|
6
7
|
declare const _default: (event: any) => Promise<any>;
|
|
7
8
|
export default _default;
|
|
8
9
|
export declare const simulateBattle: (battleInput: BgsBattleInfo, cards: AllCardsService, cardsData: CardsData) => Generator<SimulationResult, SimulationResult, void>;
|
|
9
|
-
export declare const isValidDeathrattleEnchantment: (cardId: string) => boolean;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.simulateBattle = exports.assignCards = exports.isValidDeathrattleEnchantment = void 0;
|
|
4
4
|
const reference_data_1 = require("@firestone-hs/reference-data");
|
|
5
|
-
const card_interface_1 = require("./cards/card.interface");
|
|
6
5
|
const cards_data_1 = require("./cards/cards-data");
|
|
7
|
-
const _card_mappings_1 = require("./cards/impl/_card-mappings");
|
|
8
6
|
const debug_state_1 = require("./debug-state");
|
|
9
7
|
const input_clone_1 = require("./input-clone");
|
|
10
8
|
const input_sanitation_1 = require("./input-sanitation");
|
|
11
9
|
const shared_state_1 = require("./simulation/shared-state");
|
|
12
10
|
const simulator_1 = require("./simulation/simulator");
|
|
13
11
|
const spectator_1 = require("./simulation/spectator/spectator");
|
|
12
|
+
var deathrattle_utils_1 = require("./simulation/deathrattle-utils");
|
|
13
|
+
Object.defineProperty(exports, "isValidDeathrattleEnchantment", { enumerable: true, get: function () { return deathrattle_utils_1.isValidDeathrattleEnchantment; } });
|
|
14
|
+
const MAX_SAMPLE_RESIMS = 500;
|
|
14
15
|
let globalCards = new reference_data_1.AllCardsService();
|
|
15
16
|
const assignCards = (cards) => {
|
|
16
17
|
globalCards = cards;
|
|
@@ -89,45 +90,65 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
89
90
|
...(p.chosenCardId && { chosenCardId: p.chosenCardId }),
|
|
90
91
|
}));
|
|
91
92
|
}
|
|
93
|
+
const cloneTemplate = (0, input_clone_1.buildTemplateCloner)((0, input_clone_1.cloneInput3)(inputReady));
|
|
94
|
+
const runSingleBattle = () => {
|
|
95
|
+
const input = cloneTemplate();
|
|
96
|
+
let playerInitialState = null;
|
|
97
|
+
let opponentInitialState = null;
|
|
98
|
+
const buildInitialStates = () => {
|
|
99
|
+
const inputClone = cloneTemplate();
|
|
100
|
+
playerInitialState = {
|
|
101
|
+
player: inputClone.playerBoard.player,
|
|
102
|
+
board: inputClone.playerBoard.board,
|
|
103
|
+
teammate: inputClone.playerTeammateBoard,
|
|
104
|
+
};
|
|
105
|
+
opponentInitialState = {
|
|
106
|
+
player: inputClone.opponentBoard.player,
|
|
107
|
+
board: inputClone.opponentBoard.board,
|
|
108
|
+
teammate: inputClone.opponentTeammateBoard,
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
const gameState = {
|
|
112
|
+
allCards: cards,
|
|
113
|
+
cardsData: cardsData,
|
|
114
|
+
spectator: spectator,
|
|
115
|
+
sharedState: new shared_state_1.SharedState(),
|
|
116
|
+
currentTurn: input.gameState.currentTurn,
|
|
117
|
+
validTribes: input.gameState.validTribes,
|
|
118
|
+
anomalies: input.gameState.anomalies,
|
|
119
|
+
gameState: {
|
|
120
|
+
player: {
|
|
121
|
+
player: input.playerBoard.player,
|
|
122
|
+
board: input.playerBoard.board,
|
|
123
|
+
teammate: input.playerTeammateBoard,
|
|
124
|
+
},
|
|
125
|
+
opponent: {
|
|
126
|
+
player: input.opponentBoard.player,
|
|
127
|
+
board: input.opponentBoard.board,
|
|
128
|
+
teammate: input.opponentTeammateBoard,
|
|
129
|
+
},
|
|
130
|
+
get playerInitial() {
|
|
131
|
+
if (!playerInitialState) {
|
|
132
|
+
buildInitialStates();
|
|
133
|
+
}
|
|
134
|
+
return playerInitialState;
|
|
135
|
+
},
|
|
136
|
+
get opponentInitial() {
|
|
137
|
+
if (!opponentInitialState) {
|
|
138
|
+
buildInitialStates();
|
|
139
|
+
}
|
|
140
|
+
return opponentInitialState;
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
const simulator = new simulator_1.Simulator(gameState);
|
|
145
|
+
return simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);
|
|
146
|
+
};
|
|
92
147
|
try {
|
|
93
148
|
!((_o = battleInput.options) === null || _o === void 0 ? void 0 : _o.skipInfoLogs) && console.time('simulation');
|
|
94
149
|
const outcomes = {};
|
|
95
150
|
for (let i = 0; i < numberOfSimulations; i++) {
|
|
96
|
-
const
|
|
97
|
-
const inputClone = (0, input_clone_1.cloneInput3)(inputReady);
|
|
98
|
-
const gameState = {
|
|
99
|
-
allCards: cards,
|
|
100
|
-
cardsData: cardsData,
|
|
101
|
-
spectator: spectator,
|
|
102
|
-
sharedState: new shared_state_1.SharedState(),
|
|
103
|
-
currentTurn: input.gameState.currentTurn,
|
|
104
|
-
validTribes: input.gameState.validTribes,
|
|
105
|
-
anomalies: input.gameState.anomalies,
|
|
106
|
-
gameState: {
|
|
107
|
-
player: {
|
|
108
|
-
player: input.playerBoard.player,
|
|
109
|
-
board: input.playerBoard.board,
|
|
110
|
-
teammate: input.playerTeammateBoard,
|
|
111
|
-
},
|
|
112
|
-
opponent: {
|
|
113
|
-
player: input.opponentBoard.player,
|
|
114
|
-
board: input.opponentBoard.board,
|
|
115
|
-
teammate: input.opponentTeammateBoard,
|
|
116
|
-
},
|
|
117
|
-
playerInitial: {
|
|
118
|
-
player: inputClone.playerBoard.player,
|
|
119
|
-
board: inputClone.playerBoard.board,
|
|
120
|
-
teammate: inputClone.playerTeammateBoard,
|
|
121
|
-
},
|
|
122
|
-
opponentInitial: {
|
|
123
|
-
player: inputClone.opponentBoard.player,
|
|
124
|
-
board: inputClone.opponentBoard.board,
|
|
125
|
-
teammate: inputClone.opponentTeammateBoard,
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
};
|
|
129
|
-
const simulator = new simulator_1.Simulator(gameState);
|
|
130
|
-
const battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);
|
|
151
|
+
const battleResult = runSingleBattle();
|
|
131
152
|
if (!battleResult) {
|
|
132
153
|
continue;
|
|
133
154
|
}
|
|
@@ -152,7 +173,6 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
152
173
|
else if (battleResult.result === 'tied') {
|
|
153
174
|
simulationResult.tied++;
|
|
154
175
|
}
|
|
155
|
-
spectator.commitBattleResult(battleResult.result);
|
|
156
176
|
if (Date.now() - start > maxAcceptableDuration && !hideMaxSimulationDurationWarning) {
|
|
157
177
|
console.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');
|
|
158
178
|
break;
|
|
@@ -164,6 +184,27 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
164
184
|
}
|
|
165
185
|
updateSimulationResult(simulationResult, inputReady, damageConfidence);
|
|
166
186
|
!((_q = battleInput.options) === null || _q === void 0 ? void 0 : _q.skipInfoLogs) && console.timeEnd('simulation');
|
|
187
|
+
if (includeOutcomeSamples) {
|
|
188
|
+
const neededOutcomes = [];
|
|
189
|
+
simulationResult.won > 0 && neededOutcomes.push('won');
|
|
190
|
+
simulationResult.lost > 0 && neededOutcomes.push('lost');
|
|
191
|
+
simulationResult.tied > 0 && neededOutcomes.push('tied');
|
|
192
|
+
const missingOutcomes = new Set(neededOutcomes);
|
|
193
|
+
if (missingOutcomes.size > 0) {
|
|
194
|
+
spectator.startRecording();
|
|
195
|
+
for (let i = 0; i < MAX_SAMPLE_RESIMS && missingOutcomes.size > 0; i++) {
|
|
196
|
+
const battleResult = runSingleBattle();
|
|
197
|
+
if (!(battleResult === null || battleResult === void 0 ? void 0 : battleResult.result)) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
spectator.commitBattleResult(battleResult.result);
|
|
201
|
+
if (spectator.hasSampleFor(battleResult.result)) {
|
|
202
|
+
missingOutcomes.delete(battleResult.result);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
spectator.stopRecording();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
167
208
|
spectator.prune();
|
|
168
209
|
simulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);
|
|
169
210
|
simulationResult.damageWons = [];
|
|
@@ -223,42 +264,4 @@ const checkRounding = (roundedValue, initialValue, totalValue) => {
|
|
|
223
264
|
}
|
|
224
265
|
return roundedValue;
|
|
225
266
|
};
|
|
226
|
-
const VALID_DEATHRATTLE_ENCHANTMENTS = [
|
|
227
|
-
"BG_BOT_312e",
|
|
228
|
-
"TB_BaconUps_032e",
|
|
229
|
-
"UNG_999t2e",
|
|
230
|
-
"BG21_000e",
|
|
231
|
-
"BG21_000_Ge",
|
|
232
|
-
"BG21_HERO_030p",
|
|
233
|
-
"BG21_HERO_030pe",
|
|
234
|
-
"BG22_HERO_001_Buddy_e1",
|
|
235
|
-
"BG22_HERO_001_Buddy_e2",
|
|
236
|
-
"BG22_HERO_001_Buddy_e4",
|
|
237
|
-
"BG22_HERO_001_Buddy_e3",
|
|
238
|
-
"BG22_HERO_001p_t1e",
|
|
239
|
-
"BG22_HERO_001p_t4_s",
|
|
240
|
-
"BG28_603e",
|
|
241
|
-
"BG30_MagicItem_917e",
|
|
242
|
-
"BG30_MagicItem_411e",
|
|
243
|
-
"BG30_MagicItem_952e",
|
|
244
|
-
"BG31_HERO_801ptee",
|
|
245
|
-
"BG32_172e",
|
|
246
|
-
"BG32_172_Ge",
|
|
247
|
-
"BG20_HERO_282e2",
|
|
248
|
-
];
|
|
249
|
-
const validDeathrattleEnchantmentsFromMapping = [];
|
|
250
|
-
const isValidDeathrattleEnchantment = (cardId) => {
|
|
251
|
-
if (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId)) {
|
|
252
|
-
return true;
|
|
253
|
-
}
|
|
254
|
-
if (validDeathrattleEnchantmentsFromMapping.length === 0) {
|
|
255
|
-
for (const cardImpl of Object.values(_card_mappings_1.cardMappings)) {
|
|
256
|
-
if ((0, card_interface_1.hasDeathrattleSpawnEnchantment)(cardImpl)) {
|
|
257
|
-
validDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return validDeathrattleEnchantmentsFromMapping.includes(cardId);
|
|
262
|
-
};
|
|
263
|
-
exports.isValidDeathrattleEnchantment = isValidDeathrattleEnchantment;
|
|
264
267
|
//# sourceMappingURL=simulate-bgs-battle.js.map
|