@firestone-hs/simulate-bgs-battle 1.1.726 → 1.1.727
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/bgs-battle-info.d.ts +1 -0
- package/dist/bgs-battle-info.js.map +1 -1
- package/dist/bgs-battle-options.d.ts +1 -0
- package/dist/bgs-battle-options.js.map +1 -1
- package/dist/cards/impl/_card-mappings.js +36 -0
- package/dist/cards/impl/_card-mappings.js.map +1 -1
- package/dist/cards/impl/hero-power/die-insects.d.ts +2 -0
- package/dist/cards/impl/hero-power/die-insects.js +21 -0
- package/dist/cards/impl/hero-power/die-insects.js.map +1 -0
- package/dist/cards/impl/hero-power/fire-the-cannons.d.ts +2 -0
- package/dist/cards/impl/hero-power/fire-the-cannons.js +21 -0
- package/dist/cards/impl/hero-power/fire-the-cannons.js.map +1 -0
- package/dist/cards/impl/hero-power/murloc-king-enchantment.d.ts +2 -0
- package/dist/cards/impl/hero-power/murloc-king-enchantment.js +9 -0
- package/dist/cards/impl/hero-power/murloc-king-enchantment.js.map +1 -0
- package/dist/cards/impl/hero-power/murloc-king.d.ts +2 -0
- package/dist/cards/impl/hero-power/murloc-king.js +24 -0
- package/dist/cards/impl/hero-power/murloc-king.js.map +1 -0
- package/dist/cards/impl/hero-power/nefarious-fire.d.ts +2 -0
- package/dist/cards/impl/hero-power/nefarious-fire.js +19 -0
- package/dist/cards/impl/hero-power/nefarious-fire.js.map +1 -0
- package/dist/cards/impl/hero-power/wax-warband.js +5 -1
- package/dist/cards/impl/hero-power/wax-warband.js.map +1 -1
- package/dist/cards/impl/minion/arfus.d.ts +2 -0
- package/dist/cards/impl/minion/arfus.js +17 -0
- package/dist/cards/impl/minion/arfus.js.map +1 -0
- package/dist/cards/impl/minion/branns-epic-egg.d.ts +2 -0
- package/dist/cards/impl/minion/branns-epic-egg.js +23 -0
- package/dist/cards/impl/minion/branns-epic-egg.js.map +1 -0
- package/dist/cards/impl/minion/choral-mrrrglr.js +15 -5
- package/dist/cards/impl/minion/choral-mrrrglr.js.map +1 -1
- package/dist/cards/impl/minion/elder-taggawag.d.ts +2 -5
- package/dist/cards/impl/minion/elder-taggawag.js +1 -0
- package/dist/cards/impl/minion/elder-taggawag.js.map +1 -1
- package/dist/cards/impl/minion/elementium-squirrel-bomb.d.ts +2 -0
- package/dist/cards/impl/minion/elementium-squirrel-bomb.js +22 -0
- package/dist/cards/impl/minion/elementium-squirrel-bomb.js.map +1 -0
- package/dist/cards/impl/minion/kilrek.d.ts +2 -0
- package/dist/cards/impl/minion/kilrek.js +18 -0
- package/dist/cards/impl/minion/kilrek.js.map +1 -0
- package/dist/cards/impl/minion/lady-sinestra.d.ts +2 -0
- package/dist/cards/impl/minion/lady-sinestra.js +14 -0
- package/dist/cards/impl/minion/lady-sinestra.js.map +1 -0
- package/dist/cards/impl/minion/loyal-henchman.d.ts +2 -0
- package/dist/cards/impl/minion/loyal-henchman.js +21 -0
- package/dist/cards/impl/minion/loyal-henchman.js.map +1 -0
- package/dist/cards/impl/minion/mawsworn-soulkeeper.d.ts +2 -0
- package/dist/cards/impl/minion/mawsworn-soulkeeper.js +21 -0
- package/dist/cards/impl/minion/mawsworn-soulkeeper.js.map +1 -0
- package/dist/cards/impl/minion/probius.d.ts +2 -0
- package/dist/cards/impl/minion/probius.js +16 -0
- package/dist/cards/impl/minion/probius.js.map +1 -0
- package/dist/cards/impl/minion/sr-tomb-diver.d.ts +2 -0
- package/dist/cards/impl/minion/sr-tomb-diver.js +18 -0
- package/dist/cards/impl/minion/sr-tomb-diver.js.map +1 -0
- package/dist/cards/impl/minion/stalwart-kodo.js +3 -1
- package/dist/cards/impl/minion/stalwart-kodo.js.map +1 -1
- package/dist/cards/impl/minion/timewarped-mrrrglr.js +11 -5
- package/dist/cards/impl/minion/timewarped-mrrrglr.js.map +1 -1
- package/dist/cards/impl/minion/tuskarr-raider.d.ts +2 -0
- package/dist/cards/impl/minion/tuskarr-raider.js +36 -0
- package/dist/cards/impl/minion/tuskarr-raider.js.map +1 -0
- package/dist/cards/impl/minion/twilight-hatchling.js +1 -4
- package/dist/cards/impl/minion/twilight-hatchling.js.map +1 -1
- package/dist/cards/impl/minion/unearthed-underling.d.ts +2 -0
- package/dist/cards/impl/minion/unearthed-underling.js +14 -0
- package/dist/cards/impl/minion/unearthed-underling.js.map +1 -0
- package/dist/cards/impl/spell/fleeting-vigor.js +6 -1
- package/dist/cards/impl/spell/fleeting-vigor.js.map +1 -1
- package/dist/input-clone.js +5 -1
- package/dist/input-clone.js.map +1 -1
- package/dist/input-sanitation.js +3 -0
- package/dist/input-sanitation.js.map +1 -1
- package/dist/services/rng.d.ts +8 -0
- package/dist/services/rng.js +40 -0
- package/dist/services/rng.js.map +1 -0
- package/dist/services/utils.js +3 -2
- package/dist/services/utils.js.map +1 -1
- package/dist/simulate-bgs-battle.d.ts +10 -0
- package/dist/simulate-bgs-battle.js +119 -77
- package/dist/simulate-bgs-battle.js.map +1 -1
- package/dist/simulation/add-minion-to-board.js +8 -6
- package/dist/simulation/add-minion-to-board.js.map +1 -1
- package/dist/simulation/auras.js +42 -41
- package/dist/simulation/auras.js.map +1 -1
- package/dist/simulation/damage-cap.d.ts +2 -0
- package/dist/simulation/damage-cap.js +28 -0
- package/dist/simulation/damage-cap.js.map +1 -0
- package/dist/simulation/deathrattle-spawns.js +0 -57
- package/dist/simulation/deathrattle-spawns.js.map +1 -1
- package/dist/simulation/internal-game-state.d.ts +2 -0
- package/dist/simulation/internal-game-state.js.map +1 -1
- package/dist/simulation/reborn.js +0 -13
- package/dist/simulation/reborn.js.map +1 -1
- package/dist/simulation/shared-state.d.ts +3 -1
- package/dist/simulation/shared-state.js +4 -1
- package/dist/simulation/shared-state.js.map +1 -1
- package/dist/simulation/simulator.d.ts +1 -0
- package/dist/simulation/simulator.js +13 -4
- package/dist/simulation/simulator.js.map +1 -1
- package/dist/simulation/spawns.js +1 -1
- package/dist/simulation/spawns.js.map +1 -1
- package/dist/simulation/start-of-combat/soc-action-processor.js +12 -0
- package/dist/simulation/start-of-combat/soc-action-processor.js.map +1 -1
- package/dist/simulation/stats.js +41 -24
- package/dist/simulation/stats.js.map +1 -1
- package/dist/utils.js +4 -4
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timewarped-mrrrglr.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-mrrrglr.ts"],"names":[],"mappings":";;;AAAA,iEAAoD;AAGpD,uDAA2D;AAE3D,qDAAwD;AACxD,0CAAiD;AAGpC,QAAA,iBAAiB,GAAsB;IACnD,OAAO,EAAE,sCAAsF;IAC/F,mBAAmB,EAAE,iBAAiB;IACtC,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;;QACvD,MAAM,OAAO,GAAG,IAAA,sBAAa,EAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAEzD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,uBAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAElF,MAAM,
|
|
1
|
+
{"version":3,"file":"timewarped-mrrrglr.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-mrrrglr.ts"],"names":[],"mappings":";;;AAAA,iEAAoD;AAGpD,uDAA2D;AAE3D,qDAAwD;AACxD,0CAAiD;AAGpC,QAAA,iBAAiB,GAAsB;IACnD,OAAO,EAAE,sCAAsF;IAC/F,mBAAmB,EAAE,iBAAiB;IACtC,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;;QACvD,MAAM,OAAO,GAAG,IAAA,sBAAa,EAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAEzD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,uBAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAElF,MAAM,QAAQ,GAAG,CAAC,MAAA,KAAK,CAAC,YAAY,CAAC,IAAI,mCAAI,EAAE,CAAC,CAAC,MAAM,CACtD,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,CAAC,CAAA,MAAA,CAAC,CAAC,YAAY,0CAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,sBAAsB,CAAC,CAAA,CAAA,EAAA,CAC9E,CAAC;QACF,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,MAAM,mCAAI,CAAC,CAAA,EAAA,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACxF,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,MAAM,mCAAI,CAAC,CAAA,EAAA,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAGxF,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,WACnD,OAAA,MAAA,CAAC,CAAC,YAAY,0CAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,gBAA4C,CAAC,CAAA,EAAA,CACvF,CAAC;QACF,MAAM,UAAU,GACf,iBAAiB;YACjB,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,gBAAgB,CAAC;YAC9F,CAAC,CAAC;QACH,MAAM,UAAU,GACf,iBAAiB;YACjB,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,gBAAgB,CAAC;YAC9F,CAAC,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE;YAC9B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;gBAC7B,IACC,IAAA,uBAAe,EACd,MAAM,EACN,KAAK,CAAC,YAAY,EAClB,qBAAI,CAAC,MAAM,EACX,KAAK,CAAC,SAAS,CAAC,SAAS,EACzB,KAAK,CAAC,SAAS,CAAC,QAAQ,CACxB,EACA;oBACD,IAAA,mBAAW,EACV,MAAM,EACN,MAAM,EACN,UAAU,EACV,UAAU,EACV,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,SAAS,CACf,CAAC;iBACF;aACD;SACD;QACD,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC","sourcesContent":["import { Race } from '@firestone-hs/reference-data';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { getNeighbours } from '../../../simulation/attack';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { hasCorrectTribe } from '../../../utils';\r\nimport { StartOfCombatCard } from '../../card.interface';\r\n\r\nexport const TimewarpedMrrrglr: StartOfCombatCard = {\r\n\tcardIds: [CardIds.TimewarpedMrrrglr_BG34_Giant_321, CardIds.TimewarpedMrrrglr_BG34_Giant_321_G],\r\n\tstartOfCombatTiming: 'start-of-combat',\r\n\tstartOfCombat: (minion: BoardEntity, input: SoCInput) => {\r\n\t\tconst targets = getNeighbours(input.playerBoard, minion);\r\n\t\t// Multiplier not needed if relying on global info?\r\n\t\tconst mult = minion.cardId === CardIds.TimewarpedMrrrglr_BG34_Giant_321_G ? 2 : 1;\r\n\t\t// When it's summoned by Y'Shaarj hero power, the info isn't set\r\n\t\tconst realHand = (input.playerEntity.hand ?? []).filter(\r\n\t\t\t(e) => !e.enchantments?.some((ench) => ench.cardId === 'TB_BaconShopBadsongE'),\r\n\t\t);\r\n\t\tconst totalAttackInHand = realHand.map((e) => e.attack ?? 0).reduce((a, b) => a + b, 0);\r\n\t\tconst totalHealthInHand = realHand.map((e) => e.health ?? 0).reduce((a, b) => a + b, 0);\r\n\t\t// Same as ChoralMrrrglr: globalInfo Choral*Buff duplicates stats already on board when\r\n\t\t// the Chorus enchantment is present and hand extract is empty.\r\n\t\tconst boardHasChorus = input.playerBoard.some((e) =>\r\n\t\t\te.enchantments?.some((ench) => ench.cardId === CardIds.ChoralMrrrglr_ChorusEnchantment),\r\n\t\t);\r\n\t\tconst attackBuff =\r\n\t\t\ttotalAttackInHand ||\r\n\t\t\t(boardHasChorus || minion.gildedInCombat ? 0 : input.playerEntity.globalInfo.ChoralAttackBuff) ||\r\n\t\t\t0;\r\n\t\tconst healthBuff =\r\n\t\t\ttotalHealthInHand ||\r\n\t\t\t(boardHasChorus || minion.gildedInCombat ? 0 : input.playerEntity.globalInfo.ChoralHealthBuff) ||\r\n\t\t\t0;\r\n\t\tfor (let i = 0; i < mult; i++) {\r\n\t\t\tfor (const target of targets) {\r\n\t\t\t\tif (\r\n\t\t\t\t\thasCorrectTribe(\r\n\t\t\t\t\t\ttarget,\r\n\t\t\t\t\t\tinput.playerEntity,\r\n\t\t\t\t\t\tRace.MURLOC,\r\n\t\t\t\t\t\tinput.gameState.anomalies,\r\n\t\t\t\t\t\tinput.gameState.allCards,\r\n\t\t\t\t\t)\r\n\t\t\t\t) {\r\n\t\t\t\t\tmodifyStats(\r\n\t\t\t\t\t\ttarget,\r\n\t\t\t\t\t\tminion,\r\n\t\t\t\t\t\tattackBuff,\r\n\t\t\t\t\t\thealthBuff,\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.gameState,\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\treturn true;\r\n\t},\r\n};\r\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TuskarrRaider = void 0;
|
|
4
|
+
const utils_1 = require("../../../services/utils");
|
|
5
|
+
const cards_in_hand_1 = require("../../../simulation/cards-in-hand");
|
|
6
|
+
const grantRandomBounty = (mult, hero, board, gameState) => {
|
|
7
|
+
const cardsToAdd = [];
|
|
8
|
+
for (let i = 0; i < mult; i++) {
|
|
9
|
+
const bounty = (0, utils_1.pickRandom)(gameState.cardsData.bountyTavernSpellIds);
|
|
10
|
+
if (bounty) {
|
|
11
|
+
cardsToAdd.push(bounty);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
if (cardsToAdd.length) {
|
|
15
|
+
(0, cards_in_hand_1.addCardsInHand)(hero, board, cardsToAdd, gameState);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
exports.TuskarrRaider = {
|
|
19
|
+
cardIds: ["TB_BaconShop_HERO_18_Buddy", "TB_BaconShop_HERO_18_Buddy_G"],
|
|
20
|
+
battlecry: (minion, input) => {
|
|
21
|
+
const mult = minion.cardId === "TB_BaconShop_HERO_18_Buddy_G" ? 2 : 1;
|
|
22
|
+
grantRandomBounty(mult, input.hero, input.board, input.gameState);
|
|
23
|
+
return true;
|
|
24
|
+
},
|
|
25
|
+
deathrattleSpawn: (minion, input) => {
|
|
26
|
+
const mult = minion.cardId === "TB_BaconShop_HERO_18_Buddy_G" ? 2 : 1;
|
|
27
|
+
grantRandomBounty(mult, input.boardWithDeadEntityHero, input.boardWithDeadEntity, input.gameState);
|
|
28
|
+
return [];
|
|
29
|
+
},
|
|
30
|
+
rally: (minion, input) => {
|
|
31
|
+
const mult = minion.cardId === "TB_BaconShop_HERO_18_Buddy_G" ? 2 : 1;
|
|
32
|
+
grantRandomBounty(mult, input.attackingHero, input.attackingBoard, input.gameState);
|
|
33
|
+
return { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=tuskarr-raider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tuskarr-raider.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/tuskarr-raider.ts"],"names":[],"mappings":";;;AAGA,mDAAqD;AAErD,qEAAmE;AAMnE,MAAM,iBAAiB,GAAG,CACzB,IAAY,EACZ,IAAqB,EACrB,KAAoB,EACpB,SAAwB,EACjB,EAAE;IACT,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,SAAS,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACpE,IAAI,MAAM,EAAE;YACX,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SACxB;KACD;IACD,IAAI,UAAU,CAAC,MAAM,EAAE;QACtB,IAAA,8BAAc,EAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;KACnD;AACF,CAAC,CAAC;AAEW,QAAA,aAAa,GAAqD;IAC9E,OAAO,EAAE,8DAAsG;IAC/G,SAAS,EAAE,CAAC,MAAmB,EAAE,KAAqB,EAAW,EAAE;QAClE,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,mCAAuD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC;IACb,CAAC;IACD,gBAAgB,EAAE,CAAC,MAAmB,EAAE,KAAgC,EAAE,EAAE;QAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,mCAAuD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACnG,OAAO,EAAE,CAAC;IACX,CAAC;IACD,KAAK,EAAE,CAAC,MAAmB,EAAE,KAAoB,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,mCAAuD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACpF,OAAO,EAAE,iBAAiB,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;CACD,CAAC","sourcesContent":["import { BgsPlayerEntity } from '../../../bgs-player-entity';\r\nimport { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { pickRandom } from '../../../services/utils';\r\nimport { BattlecryInput } from '../../../simulation/battlecries';\r\nimport { addCardsInHand } from '../../../simulation/cards-in-hand';\r\nimport { DeathrattleTriggeredInput } from '../../../simulation/deathrattle-on-trigger';\r\nimport { FullGameState } from '../../../simulation/internal-game-state';\r\nimport { OnAttackInput } from '../../../simulation/on-attack';\r\nimport { BattlecryCard, DeathrattleSpawnCard, RallyCard } from '../../card.interface';\r\n\r\nconst grantRandomBounty = (\r\n\tmult: number,\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst cardsToAdd: string[] = [];\r\n\tfor (let i = 0; i < mult; i++) {\r\n\t\tconst bounty = pickRandom(gameState.cardsData.bountyTavernSpellIds);\r\n\t\tif (bounty) {\r\n\t\t\tcardsToAdd.push(bounty);\r\n\t\t}\r\n\t}\r\n\tif (cardsToAdd.length) {\r\n\t\taddCardsInHand(hero, board, cardsToAdd, gameState);\r\n\t}\r\n};\r\n\r\nexport const TuskarrRaider: BattlecryCard & DeathrattleSpawnCard & RallyCard = {\r\n\tcardIds: [CardIds.TuskarrRaider_TB_BaconShop_HERO_18_Buddy, CardIds.TuskarrRaider_TB_BaconShop_HERO_18_Buddy_G],\r\n\tbattlecry: (minion: BoardEntity, input: BattlecryInput): boolean => {\r\n\t\tconst mult = minion.cardId === CardIds.TuskarrRaider_TB_BaconShop_HERO_18_Buddy_G ? 2 : 1;\r\n\t\tgrantRandomBounty(mult, input.hero, input.board, input.gameState);\r\n\t\treturn true;\r\n\t},\r\n\tdeathrattleSpawn: (minion: BoardEntity, input: DeathrattleTriggeredInput) => {\r\n\t\tconst mult = minion.cardId === CardIds.TuskarrRaider_TB_BaconShop_HERO_18_Buddy_G ? 2 : 1;\r\n\t\tgrantRandomBounty(mult, input.boardWithDeadEntityHero, input.boardWithDeadEntity, input.gameState);\r\n\t\treturn [];\r\n\t},\r\n\trally: (minion: BoardEntity, input: OnAttackInput) => {\r\n\t\tconst mult = minion.cardId === CardIds.TuskarrRaider_TB_BaconShop_HERO_18_Buddy_G ? 2 : 1;\r\n\t\tgrantRandomBounty(mult, input.attackingHero, input.attackingBoard, input.gameState);\r\n\t\treturn { dmgDoneByAttacker: 0, dmgDoneByDefender: 0 };\r\n\t},\r\n};\r\n"]}
|
|
@@ -12,10 +12,7 @@ exports.TwilightHatchling = {
|
|
|
12
12
|
e.attackImmediately = true;
|
|
13
13
|
});
|
|
14
14
|
const indexFromRight = input.deadEntityIndexFromRight;
|
|
15
|
-
|
|
16
|
-
spawned.forEach((e) => {
|
|
17
|
-
e.hasAttacked = undefined;
|
|
18
|
-
});
|
|
15
|
+
(0, spawns_1.performEntitySpawns)(spawns, input.boardWithDeadEntity, input.boardWithDeadEntityHero, minion, indexFromRight, input.otherBoard, input.otherBoardHero, input.gameState, true);
|
|
19
16
|
return [];
|
|
20
17
|
},
|
|
21
18
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"twilight-hatchling.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/twilight-hatchling.ts"],"names":[],"mappings":";;;AAGA,+EAAiF;AACjF,uDAAiE;AAGpD,QAAA,iBAAiB,GAAyB;IACtD,OAAO,EAAE,0BAA0E;IACnF,gBAAgB,EAAE,CAAC,MAAmB,EAAE,KAAgC,EAA0B,EAAE;QACnG,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,iBAAyC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5E,MAAM,MAAM,GAAG,IAAA,4CAAuB,eAAyD,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5G,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACpB,CAAC,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,KAAK,CAAC,wBAAwB,CAAC;QACtD,
|
|
1
|
+
{"version":3,"file":"twilight-hatchling.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/twilight-hatchling.ts"],"names":[],"mappings":";;;AAGA,+EAAiF;AACjF,uDAAiE;AAGpD,QAAA,iBAAiB,GAAyB;IACtD,OAAO,EAAE,0BAA0E;IACnF,gBAAgB,EAAE,CAAC,MAAmB,EAAE,KAAgC,EAA0B,EAAE;QACnG,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,iBAAyC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5E,MAAM,MAAM,GAAG,IAAA,4CAAuB,eAAyD,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5G,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;YACpB,CAAC,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,KAAK,CAAC,wBAAwB,CAAC;QACtD,IAAA,4BAAmB,EAClB,MAAM,EACN,KAAK,CAAC,mBAAmB,EACzB,KAAK,CAAC,uBAAuB,EAC7B,MAAM,EACN,cAAc,EACd,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EACf,IAAI,CACJ,CAAC;QAOF,OAAO,EAAE,CAAC;IACX,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 { simplifiedSpawnEntities } from '../../../simulation/deathrattle-spawns';\r\nimport { performEntitySpawns } from '../../../simulation/spawns';\r\nimport { DeathrattleSpawnCard } from '../../card.interface';\r\n\r\nexport const TwilightHatchling: DeathrattleSpawnCard = {\r\n\tcardIds: [CardIds.TwilightHatchling_BG34_630, CardIds.TwilightHatchling_BG34_630_G],\r\n\tdeathrattleSpawn: (minion: BoardEntity, input: DeathrattleTriggeredInput): readonly BoardEntity[] => {\r\n\t\tconst mult = minion.cardId === CardIds.TwilightHatchling_BG34_630_G ? 2 : 1;\r\n\r\n\t\tconst spawns = simplifiedSpawnEntities(CardIds.TwilightHatchling_TwilightWhelpToken_BG34_630t, mult, input);\r\n\t\tspawns.forEach((e) => {\r\n\t\t\te.attackImmediately = true;\r\n\t\t});\r\n\t\tconst indexFromRight = input.deadEntityIndexFromRight;\r\n\t\tperformEntitySpawns(\r\n\t\t\tspawns,\r\n\t\t\tinput.boardWithDeadEntity,\r\n\t\t\tinput.boardWithDeadEntityHero,\r\n\t\t\tminion,\r\n\t\t\tindexFromRight,\r\n\t\t\tinput.otherBoard,\r\n\t\t\tinput.otherBoardHero,\r\n\t\t\tinput.gameState,\r\n\t\t\ttrue,\r\n\t\t);\r\n\t\t// Do not clear hasAttacked after attack-immediately. With after-spawn (Stalwart Kodo)\r\n\t\t// resolving before the immediate attack, clearing hasAttacked let whelps swing a second\r\n\t\t// time at full Kodo stats in the same combat segment — far above live.\r\n\t\t// Prior note (re-attack after weak pre-Kodo immediate attack):\r\n\t\t// https://replays.firestoneapp.com/?reviewId=7c838df7-992b-4dae-ad96-c0f8a0d7872a&turn=7&action=0\r\n\r\n\t\treturn [];\r\n\t},\r\n};\r\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnearthedUnderling = void 0;
|
|
4
|
+
const stats_1 = require("../../../simulation/stats");
|
|
5
|
+
exports.UnearthedUnderling = {
|
|
6
|
+
cardIds: ["TB_BaconShop_HERO_25_Buddy", "TB_BaconShop_HERO_25_Buddy_G"],
|
|
7
|
+
afterHeroDamaged: (minion, input) => {
|
|
8
|
+
input.hero.hpLeft = input.hero.hpLeft + input.damage;
|
|
9
|
+
const mult = minion.cardId === "TB_BaconShop_HERO_25_Buddy_G" ? 2 : 1;
|
|
10
|
+
const buff = input.damage * mult;
|
|
11
|
+
(0, stats_1.modifyStats)(minion, minion, buff, buff, input.board, input.hero, input.gameState);
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=unearthed-underling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unearthed-underling.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/unearthed-underling.ts"],"names":[],"mappings":";;;AAGA,qDAAwD;AAG3C,QAAA,kBAAkB,GAAyB;IACvD,OAAO,EAAE,8DAAgH;IACzH,gBAAgB,EAAE,CAAC,MAAmB,EAAE,KAA4B,EAAE,EAAE;QACvE,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,mCAA4D,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACjC,IAAA,mBAAW,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACnF,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { AfterHeroDamagedInput } from '../../../simulation/damage-to-hero';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { AfterHeroDamagedCard } from '../../card.interface';\r\n\r\nexport const UnearthedUnderling: AfterHeroDamagedCard = {\r\n\tcardIds: [CardIds.UnearthedUnderling_TB_BaconShop_HERO_25_Buddy, CardIds.UnearthedUnderling_TB_BaconShop_HERO_25_Buddy_G],\r\n\tafterHeroDamaged: (minion: BoardEntity, input: AfterHeroDamagedInput) => {\r\n\t\tinput.hero.hpLeft = input.hero.hpLeft + input.damage;\r\n\t\tconst mult = minion.cardId === CardIds.UnearthedUnderling_TB_BaconShop_HERO_25_Buddy_G ? 2 : 1;\r\n\t\tconst buff = input.damage * mult;\r\n\t\tmodifyStats(minion, minion, buff, buff, input.board, input.hero, input.gameState);\r\n\t},\r\n};\r\n"]}
|
|
@@ -4,7 +4,12 @@ exports.FleetingVigor = void 0;
|
|
|
4
4
|
const utils_1 = require("../../../utils");
|
|
5
5
|
exports.FleetingVigor = {
|
|
6
6
|
startOfCombat: (secret, input) => {
|
|
7
|
-
|
|
7
|
+
const atk = Number.isFinite(secret.scriptDataNum1) ? secret.scriptDataNum1 : 0;
|
|
8
|
+
const hp = Number.isFinite(secret.scriptDataNum2) ? secret.scriptDataNum2 : 0;
|
|
9
|
+
if (atk === 0 && hp === 0) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
(0, utils_1.addStatsToBoard)(secret, input.playerBoard, input.playerEntity, atk, hp, input.gameState);
|
|
8
13
|
return true;
|
|
9
14
|
},
|
|
10
15
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fleeting-vigor.js","sourceRoot":"","sources":["../../../../src/cards/impl/spell/fleeting-vigor.ts"],"names":[],"mappings":";;;AAEA,0CAAiD;AAEpC,QAAA,aAAa,GAAG;IAC5B,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;QACvD,
|
|
1
|
+
{"version":3,"file":"fleeting-vigor.js","sourceRoot":"","sources":["../../../../src/cards/impl/spell/fleeting-vigor.ts"],"names":[],"mappings":";;;AAEA,0CAAiD;AAEpC,QAAA,aAAa,GAAG;IAC5B,aAAa,EAAE,CAAC,MAAmB,EAAE,KAAe,EAAE,EAAE;QACvD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,cAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3F,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAE,MAAM,CAAC,cAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;YAC1B,OAAO,KAAK,CAAC;SACb;QACD,IAAA,uBAAe,EAAC,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC;IACb,CAAC;CACD,CAAC","sourcesContent":["import { BoardSecret } from '../../../board-secret';\r\nimport { SoCInput } from '../../../simulation/start-of-combat/start-of-combat-input';\r\nimport { addStatsToBoard } from '../../../utils';\r\n\r\nexport const FleetingVigor = {\r\n\tstartOfCombat: (secret: BoardSecret, input: SoCInput) => {\r\n\t\tconst atk = Number.isFinite(secret.scriptDataNum1) ? (secret.scriptDataNum1 as number) : 0;\r\n\t\tconst hp = Number.isFinite(secret.scriptDataNum2) ? (secret.scriptDataNum2 as number) : 0;\r\n\t\tif (atk === 0 && hp === 0) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\taddStatsToBoard(secret, input.playerBoard, input.playerEntity, atk, hp, input.gameState);\r\n\t\treturn true;\r\n\t},\r\n};\r\n"]}
|
package/dist/input-clone.js
CHANGED
|
@@ -14,9 +14,11 @@ const buildTemplateCloner = (template) => {
|
|
|
14
14
|
};
|
|
15
15
|
exports.buildTemplateCloner = buildTemplateCloner;
|
|
16
16
|
const cloneInput3 = (input) => {
|
|
17
|
+
var _a;
|
|
17
18
|
const result = {
|
|
18
19
|
gameState: {
|
|
19
20
|
currentTurn: input.gameState.currentTurn,
|
|
21
|
+
numberOfPlayersAlive: input.gameState.numberOfPlayersAlive,
|
|
20
22
|
anomalies: input.gameState.anomalies,
|
|
21
23
|
validTribes: input.gameState.validTribes,
|
|
22
24
|
},
|
|
@@ -25,7 +27,9 @@ const cloneInput3 = (input) => {
|
|
|
25
27
|
opponentBoard: (0, exports.cloneBoard)(input.opponentBoard),
|
|
26
28
|
playerTeammateBoard: (0, exports.cloneBoard)(input.playerTeammateBoard),
|
|
27
29
|
opponentTeammateBoard: (0, exports.cloneBoard)(input.opponentTeammateBoard),
|
|
28
|
-
options: null
|
|
30
|
+
options: ((_a = input.options) === null || _a === void 0 ? void 0 : _a.applyDamageCap)
|
|
31
|
+
? { applyDamageCap: true }
|
|
32
|
+
: null,
|
|
29
33
|
};
|
|
30
34
|
return result;
|
|
31
35
|
};
|
package/dist/input-clone.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-clone.js","sourceRoot":"","sources":["../src/input-clone.ts"],"names":[],"mappings":";;;AAmBO,MAAM,mBAAmB,GAAG,CAAC,QAAuB,EAAyB,EAAE;IACrF,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAIrC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;QACjC,IAAI;YAEH,OAAO,IAAI,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAwB,CAAC;SAC7D;QAAC,OAAO,CAAC,EAAE;SAGX;KACD;IACD,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC,CAAC;AAfW,QAAA,mBAAmB,uBAe9B;AAEK,MAAM,WAAW,GAAG,CAAC,KAAoB,EAAiB,EAAE
|
|
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\tnumberOfPlayersAlive: input.gameState.numberOfPlayersAlive,\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\t// Monte Carlo knobs are read before cloning; only combat-affecting flags must survive.\r\n\t\toptions: input.options?.applyDamageCap\r\n\t\t\t? ({ applyDamageCap: true } as BgsBattleInfo['options'])\r\n\t\t\t: 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/input-sanitation.js
CHANGED
|
@@ -48,6 +48,9 @@ const buildFinalInput = (battleInput, cards, cardsData) => {
|
|
|
48
48
|
...battleInput.gameState,
|
|
49
49
|
anomalies: (_b = (_a = battleInput.gameState.anomalies) === null || _a === void 0 ? void 0 : _a.filter((a) => !!a)) !== null && _b !== void 0 ? _b : [],
|
|
50
50
|
},
|
|
51
|
+
options: battleInput.options,
|
|
52
|
+
heroHasDied: battleInput.heroHasDied,
|
|
53
|
+
debugState: battleInput.debugState,
|
|
51
54
|
};
|
|
52
55
|
return inputReady;
|
|
53
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-sanitation.js","sourceRoot":"","sources":["../src/input-sanitation.ts"],"names":[],"mappings":"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","sourcesContent":["import { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BgsBoardInfo } from './bgs-board-info';\r\nimport { BgsHeroPower, BgsPlayerEntity } from './bgs-player-entity';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { CardIds } from './services/card-ids';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { fixEnchantments } from './simulation/enchantments';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nexport const buildFinalInput = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): BgsBattleInfo => {\r\n\tconst entityIdContainer = { entityId: 999_999_999 };\r\n\r\n\tconst {\r\n\t\tboard: playerBoard,\r\n\t\thand: playerHand,\r\n\t\tplayer: playerEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: playerTeammateBoard,\r\n\t\thand: playerTeammateHand,\r\n\t\tplayer: playerTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerTeammateBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\tconst {\r\n\t\tboard: opponentBoard,\r\n\t\thand: opponentHand,\r\n\t\tplayer: opponentEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: opponentTeammateBoard,\r\n\t\thand: opponentTeammateHand,\r\n\t\tplayer: opponentTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentTeammateBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerEntity,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tplayerTeammateBoard: !!playerTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: playerTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...playerTeammateEntity,\r\n\t\t\t\t\t\thand: playerTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentEntity,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentTeammateBoard: !!opponentTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: opponentTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...opponentTeammateEntity,\r\n\t\t\t\t\t\thand: opponentTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\tgameState: {\r\n\t\t\t...battleInput.gameState,\r\n\t\t\tanomalies: battleInput.gameState.anomalies?.filter((a) => !!a) ?? ([] as readonly string[]),\r\n\t\t},\r\n\t} as BgsBattleInfo;\r\n\treturn inputReady;\r\n};\r\n\r\nconst buildFinalInputForPlayer = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tanomalies: readonly string[],\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tentityIdContainer: { entityId: number },\r\n): { board: BoardEntity[]; hand: BoardEntity[]; player: BgsPlayerEntity } => {\r\n\tif (!playerInfo) {\r\n\t\treturn { board: [], hand: [], player: null };\r\n\t}\r\n\r\n\tconst { board, hand } = buildFinalInputBoard(playerInfo, isPlayer, cardsData, cards);\r\n\tconst isGhost = playerInfo.player?.hpLeft != null && playerInfo.player.hpLeft <= 0;\r\n\tplayerInfo.player.secrets = (playerInfo.player.secrets ?? playerInfo.secrets)?.filter((e) => !!e?.cardId) ?? [];\r\n\t// Add the scriptDataNum1 only on the start of combat phase, so that it doesn't trigger too soon\r\n\t// Don't do this, as secrets like Fleeting Vigor use this info to tell how much buff it will apply\r\n\t// playerInfo.player.secrets.forEach((secret) => (secret.scriptDataNum1 = 0));\r\n\t// Trinkets don't seem to trigger when facing the ghost\r\n\t// http://replays.firestoneapp.com/?reviewId=4ad32e03-2620-4fb1-8b43-cad55afd30fc&turn=27&action=2\r\n\t// One of the trinkets is Blood Golem Sticker, and no Blood Golem is summoned\r\n\t// Looks like that's not always the case:\r\n\t// http://replays.firestoneapp.com/?reviewId=9958e8d3-4388-4e6f-9b36-35f3a08be2f6&turn=25&action=4\r\n\t// playerInfo.player.trinkets = isGhost ? [] : playerInfo.player.trinkets?.filter((e) => !!e?.cardId) ?? [];\r\n\tconst fixedTrinkets = playerInfo.player.trinkets?.filter((e) => !!e?.cardId);\r\n\tplayerInfo.player.trinkets = (fixedTrinkets ?? []).sort((a, b) => a.entityId - b.entityId);\r\n\tplayerInfo.player.friendly = isPlayer;\r\n\tplayerInfo.player.globalInfo = playerInfo.player.globalInfo ?? {};\r\n\tplayerInfo.player.globalInfo.PirateAttackBonus = playerInfo.player.globalInfo.PirateAttackBonus ?? 0;\r\n\tplayerInfo.player.globalInfo.MechAttackBonus = playerInfo.player.globalInfo.MechAttackBonus ?? 0;\r\n\tplayerInfo.player.heroPowers = playerInfo.player.heroPowers?.length\r\n\t\t? playerInfo.player.heroPowers.map((hp, index) => sanitizeHeroPower(hp, index, playerInfo.player, cards))\r\n\t\t: [\r\n\t\t\t\t{\r\n\t\t\t\t\tcardId: playerInfo.player.heroPowerId,\r\n\t\t\t\t\tentityId: playerInfo.player.heroPowerEntityId,\r\n\t\t\t\t\tused: playerInfo.player.heroPowerUsed,\r\n\t\t\t\t\tinfo: playerInfo.player.heroPowerInfo,\r\n\t\t\t\t\tinfo2: playerInfo.player.heroPowerInfo2,\r\n\t\t\t\t} as BgsHeroPower,\r\n\t\t ];\r\n\t// playerInfo.player.heroPowerId =\r\n\t// \tplayerInfo.player.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(playerInfo.player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? playerInfo.player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \tplayerInfo.player.heroPowerId;\r\n\tplayerInfo.player.cardId = isGhost ? CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad : playerInfo.player.cardId;\r\n\tplayerInfo.player.hpLeft = Math.max(1, playerInfo.player.hpLeft);\r\n\t// When using the simulator, the aura is not applied when receiving the board state.\r\n\tsetMissingAuras(board, playerInfo.player, anomalies, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, cardsData, isPlayer, entityIdContainer);\r\n\treturn { board, hand, player: playerInfo.player };\r\n};\r\n\r\nconst sanitizeHeroPower = (\r\n\thp: BgsHeroPower,\r\n\tindex: number,\r\n\tplayer: BgsPlayerEntity,\r\n\tcards: AllCardsService,\r\n): BgsHeroPower => {\r\n\treturn hp;\r\n\t// FIXME: fix this when the situation presents itself. At the moment, we already have trinkets / hero powers / quest rewards\r\n\t// handled separately, so maybe there is no need to map a quest reward to one of Sire D.'s hero power\r\n\t// if (index !== 0) {\r\n\t// \treturn hp;\r\n\t// }\r\n\r\n\t// hp.cardId =\r\n\t// \tplayer.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \thp.cardId;\r\n\t// return hp;\r\n};\r\n\r\nconst buildFinalInputBoard = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n): { board: BoardEntity[]; hand: BoardEntity[] } => {\r\n\tconst board = playerInfo.board\r\n\t\t.map((entity) => fixEnchantments(entity, cards))\r\n\t\t.map((entity) => ({\r\n\t\t\t...entity,\r\n\t\t\tinInitialState: true,\r\n\t\t\tscriptDataNum1: cardsData.defaultScriptDataNum(entity.cardId) || entity.scriptDataNum1,\r\n\t\t}))\r\n\t\t.map((entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: isPlayer } as BoardEntity));\r\n\tconst hand =\r\n\t\tplayerInfo.player.hand\r\n\t\t\t?.map((entity) => ({ ...entity, inInitialState: true }))\r\n\t\t\t.map((entity) => fixEnchantments(entity, cards))\r\n\t\t\t.map((entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: isPlayer } as BoardEntity)) ?? [];\r\n\r\n\treturn { board, hand };\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"input-sanitation.js","sourceRoot":"","sources":["../src/input-sanitation.ts"],"names":[],"mappings":";;;AAOA,8CAA0E;AAC1E,4DAA4D;AAC5D,mCAA8C;AAEvC,MAAM,eAAe,GAAG,CAC9B,WAA0B,EAC1B,KAAsB,EACtB,SAAoB,EACJ,EAAE;;IAClB,MAAM,iBAAiB,GAAG,EAAE,QAAQ,EAAE,SAAW,EAAE,CAAC;IAEpD,MAAM,EACL,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,YAAY,GACpB,GAAG,wBAAwB,CAC3B,WAAW,CAAC,WAAW,EACvB,IAAI,EACJ,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IACF,MAAM,EACL,KAAK,EAAE,mBAAmB,EAC1B,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,oBAAoB,GAC5B,GAAG,wBAAwB,CAC3B,WAAW,CAAC,mBAAmB,EAC/B,IAAI,EACJ,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IAEF,MAAM,EACL,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACtB,GAAG,wBAAwB,CAC3B,WAAW,CAAC,aAAa,EACzB,KAAK,EACL,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IACF,MAAM,EACL,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,sBAAsB,GAC9B,GAAG,wBAAwB,CAC3B,WAAW,CAAC,qBAAqB,EACjC,KAAK,EACL,WAAW,CAAC,SAAS,CAAC,SAAS,EAC/B,KAAK,EACL,SAAS,EACT,iBAAiB,CACjB,CAAC;IAIF,MAAM,UAAU,GAAkB;QACjC,WAAW,EAAE;YACZ,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE;gBACP,GAAG,YAAY;gBACf,IAAI,EAAE,UAAU;aAChB;SACD;QACD,mBAAmB,EAAE,CAAC,CAAC,oBAAoB;YAC1C,CAAC,CAAC;gBACA,KAAK,EAAE,mBAAmB;gBAC1B,MAAM,EAAE;oBACP,GAAG,oBAAoB;oBACvB,IAAI,EAAE,kBAAkB;iBACxB;aACA;YACH,CAAC,CAAC,IAAI;QACP,aAAa,EAAE;YACd,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE;gBACP,GAAG,cAAc;gBACjB,IAAI,EAAE,YAAY;aAClB;SACD;QACD,qBAAqB,EAAE,CAAC,CAAC,sBAAsB;YAC9C,CAAC,CAAC;gBACA,KAAK,EAAE,qBAAqB;gBAC5B,MAAM,EAAE;oBACP,GAAG,sBAAsB;oBACzB,IAAI,EAAE,oBAAoB;iBAC1B;aACA;YACH,CAAC,CAAC,IAAI;QACP,SAAS,EAAE;YACV,GAAG,WAAW,CAAC,SAAS;YACxB,SAAS,EAAE,MAAA,MAAA,WAAW,CAAC,SAAS,CAAC,SAAS,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,mCAAK,EAAwB;SAC3F;QAGD,OAAO,EAAE,WAAW,CAAC,OAAO;QAC5B,WAAW,EAAE,WAAW,CAAC,WAAW;QACpC,UAAU,EAAE,WAAW,CAAC,UAAU;KACjB,CAAC;IACnB,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AAvGW,QAAA,eAAe,mBAuG1B;AAEF,MAAM,wBAAwB,GAAG,CAChC,UAAwB,EACxB,QAAiB,EACjB,SAA4B,EAC5B,KAAsB,EACtB,SAAoB,EACpB,iBAAuC,EACkC,EAAE;;IAC3E,IAAI,CAAC,UAAU,EAAE;QAChB,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;KAC7C;IAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,oBAAoB,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACrF,MAAM,OAAO,GAAG,CAAA,MAAA,UAAU,CAAC,MAAM,0CAAE,MAAM,KAAI,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACnF,UAAU,CAAC,MAAM,CAAC,OAAO,GAAG,MAAA,MAAA,CAAC,MAAA,UAAU,CAAC,MAAM,CAAC,OAAO,mCAAI,UAAU,CAAC,OAAO,CAAC,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,mCAAI,EAAE,CAAC;IAUhH,MAAM,aAAa,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,QAAQ,0CAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,CAAA,CAAC,CAAC;IAC7E,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3F,UAAU,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACtC,UAAU,CAAC,MAAM,CAAC,UAAU,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,UAAU,mCAAI,EAAE,CAAC;IAClE,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,iBAAiB,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,iBAAiB,mCAAI,CAAC,CAAC;IACrG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,GAAG,MAAA,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,mCAAI,CAAC,CAAC;IACjG,UAAU,CAAC,MAAM,CAAC,UAAU,GAAG,CAAA,MAAA,UAAU,CAAC,MAAM,CAAC,UAAU,0CAAE,MAAM;QAClE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACzG,CAAC,CAAC;YACA;gBACC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,WAAW;gBACrC,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,iBAAiB;gBAC7C,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,aAAa;gBACrC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,aAAa;gBACrC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,cAAc;aACvB;SAChB,CAAC;IAOL,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,+BAA+C,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;IAC9G,UAAU,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEjE,IAAA,uBAAe,EAAC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAK5D,IAAA,2BAAmB,EAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAC/E,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AACnD,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CACzB,EAAgB,EAChB,KAAa,EACb,MAAuB,EACvB,KAAsB,EACP,EAAE;IACjB,OAAO,EAAE,CAAC;AAcX,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAC5B,UAAwB,EACxB,QAAiB,EACjB,SAAoB,EACpB,KAAsB,EAC0B,EAAE;;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK;SAC5B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,8BAAe,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;SAC/C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACjB,GAAG,MAAM;QACT,cAAc,EAAE,IAAI;QACpB,cAAc,EAAE,SAAS,CAAC,oBAAoB,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,cAAc;KACtF,CAAC,CAAC;SACF,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAkB,CAAA,CAAC,CAAC;IACtG,MAAM,IAAI,GACT,MAAA,MAAA,UAAU,CAAC,MAAM,CAAC,IAAI,0CACnB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EACtD,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,8BAAe,EAAC,MAAM,EAAE,KAAK,CAAC,EAC9C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAkB,CAAA,CAAC,mCAAI,EAAE,CAAC;IAE7G,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC,CAAC","sourcesContent":["import { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BgsBoardInfo } from './bgs-board-info';\r\nimport { BgsHeroPower, BgsPlayerEntity } from './bgs-player-entity';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { CardIds } from './services/card-ids';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { fixEnchantments } from './simulation/enchantments';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nexport const buildFinalInput = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): BgsBattleInfo => {\r\n\tconst entityIdContainer = { entityId: 999_999_999 };\r\n\r\n\tconst {\r\n\t\tboard: playerBoard,\r\n\t\thand: playerHand,\r\n\t\tplayer: playerEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: playerTeammateBoard,\r\n\t\thand: playerTeammateHand,\r\n\t\tplayer: playerTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerTeammateBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\tconst {\r\n\t\tboard: opponentBoard,\r\n\t\thand: opponentHand,\r\n\t\tplayer: opponentEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: opponentTeammateBoard,\r\n\t\thand: opponentTeammateHand,\r\n\t\tplayer: opponentTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentTeammateBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerEntity,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tplayerTeammateBoard: !!playerTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: playerTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...playerTeammateEntity,\r\n\t\t\t\t\t\thand: playerTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentEntity,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentTeammateBoard: !!opponentTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: opponentTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...opponentTeammateEntity,\r\n\t\t\t\t\t\thand: opponentTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\tgameState: {\r\n\t\t\t...battleInput.gameState,\r\n\t\t\tanomalies: battleInput.gameState.anomalies?.filter((a) => !!a) ?? ([] as readonly string[]),\r\n\t\t},\r\n\t\t// Combat-affecting options (e.g. applyDamageCap) must survive into runSingleBattle;\r\n\t\t// Monte Carlo knobs are still read from the original battleInput before cloning.\r\n\t\toptions: battleInput.options,\r\n\t\theroHasDied: battleInput.heroHasDied,\r\n\t\tdebugState: battleInput.debugState,\r\n\t} as BgsBattleInfo;\r\n\treturn inputReady;\r\n};\r\n\r\nconst buildFinalInputForPlayer = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tanomalies: readonly string[],\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tentityIdContainer: { entityId: number },\r\n): { board: BoardEntity[]; hand: BoardEntity[]; player: BgsPlayerEntity } => {\r\n\tif (!playerInfo) {\r\n\t\treturn { board: [], hand: [], player: null };\r\n\t}\r\n\r\n\tconst { board, hand } = buildFinalInputBoard(playerInfo, isPlayer, cardsData, cards);\r\n\tconst isGhost = playerInfo.player?.hpLeft != null && playerInfo.player.hpLeft <= 0;\r\n\tplayerInfo.player.secrets = (playerInfo.player.secrets ?? playerInfo.secrets)?.filter((e) => !!e?.cardId) ?? [];\r\n\t// Add the scriptDataNum1 only on the start of combat phase, so that it doesn't trigger too soon\r\n\t// Don't do this, as secrets like Fleeting Vigor use this info to tell how much buff it will apply\r\n\t// playerInfo.player.secrets.forEach((secret) => (secret.scriptDataNum1 = 0));\r\n\t// Trinkets don't seem to trigger when facing the ghost\r\n\t// http://replays.firestoneapp.com/?reviewId=4ad32e03-2620-4fb1-8b43-cad55afd30fc&turn=27&action=2\r\n\t// One of the trinkets is Blood Golem Sticker, and no Blood Golem is summoned\r\n\t// Looks like that's not always the case:\r\n\t// http://replays.firestoneapp.com/?reviewId=9958e8d3-4388-4e6f-9b36-35f3a08be2f6&turn=25&action=4\r\n\t// playerInfo.player.trinkets = isGhost ? [] : playerInfo.player.trinkets?.filter((e) => !!e?.cardId) ?? [];\r\n\tconst fixedTrinkets = playerInfo.player.trinkets?.filter((e) => !!e?.cardId);\r\n\tplayerInfo.player.trinkets = (fixedTrinkets ?? []).sort((a, b) => a.entityId - b.entityId);\r\n\tplayerInfo.player.friendly = isPlayer;\r\n\tplayerInfo.player.globalInfo = playerInfo.player.globalInfo ?? {};\r\n\tplayerInfo.player.globalInfo.PirateAttackBonus = playerInfo.player.globalInfo.PirateAttackBonus ?? 0;\r\n\tplayerInfo.player.globalInfo.MechAttackBonus = playerInfo.player.globalInfo.MechAttackBonus ?? 0;\r\n\tplayerInfo.player.heroPowers = playerInfo.player.heroPowers?.length\r\n\t\t? playerInfo.player.heroPowers.map((hp, index) => sanitizeHeroPower(hp, index, playerInfo.player, cards))\r\n\t\t: [\r\n\t\t\t\t{\r\n\t\t\t\t\tcardId: playerInfo.player.heroPowerId,\r\n\t\t\t\t\tentityId: playerInfo.player.heroPowerEntityId,\r\n\t\t\t\t\tused: playerInfo.player.heroPowerUsed,\r\n\t\t\t\t\tinfo: playerInfo.player.heroPowerInfo,\r\n\t\t\t\t\tinfo2: playerInfo.player.heroPowerInfo2,\r\n\t\t\t\t} as BgsHeroPower,\r\n\t\t ];\r\n\t// playerInfo.player.heroPowerId =\r\n\t// \tplayerInfo.player.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(playerInfo.player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? playerInfo.player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \tplayerInfo.player.heroPowerId;\r\n\tplayerInfo.player.cardId = isGhost ? CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad : playerInfo.player.cardId;\r\n\tplayerInfo.player.hpLeft = Math.max(1, playerInfo.player.hpLeft);\r\n\t// When using the simulator, the aura is not applied when receiving the board state.\r\n\tsetMissingAuras(board, playerInfo.player, anomalies, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, cardsData, isPlayer, entityIdContainer);\r\n\treturn { board, hand, player: playerInfo.player };\r\n};\r\n\r\nconst sanitizeHeroPower = (\r\n\thp: BgsHeroPower,\r\n\tindex: number,\r\n\tplayer: BgsPlayerEntity,\r\n\tcards: AllCardsService,\r\n): BgsHeroPower => {\r\n\treturn hp;\r\n\t// FIXME: fix this when the situation presents itself. At the moment, we already have trinkets / hero powers / quest rewards\r\n\t// handled separately, so maybe there is no need to map a quest reward to one of Sire D.'s hero power\r\n\t// if (index !== 0) {\r\n\t// \treturn hp;\r\n\t// }\r\n\r\n\t// hp.cardId =\r\n\t// \tplayer.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \thp.cardId;\r\n\t// return hp;\r\n};\r\n\r\nconst buildFinalInputBoard = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n): { board: BoardEntity[]; hand: BoardEntity[] } => {\r\n\tconst board = playerInfo.board\r\n\t\t.map((entity) => fixEnchantments(entity, cards))\r\n\t\t.map((entity) => ({\r\n\t\t\t...entity,\r\n\t\t\tinInitialState: true,\r\n\t\t\tscriptDataNum1: cardsData.defaultScriptDataNum(entity.cardId) || entity.scriptDataNum1,\r\n\t\t}))\r\n\t\t.map((entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: isPlayer } as BoardEntity));\r\n\tconst hand =\r\n\t\tplayerInfo.player.hand\r\n\t\t\t?.map((entity) => ({ ...entity, inInitialState: true }))\r\n\t\t\t.map((entity) => fixEnchantments(entity, cards))\r\n\t\t\t.map((entity) => ({ ...addImpliedMechanics(entity, cardsData), friendly: isPlayer } as BoardEntity)) ?? [];\r\n\r\n\treturn { board, hand };\r\n};\r\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface Rng {
|
|
2
|
+
next(): number;
|
|
3
|
+
}
|
|
4
|
+
export declare const defaultRng: Rng;
|
|
5
|
+
export declare const getActiveRng: () => Rng;
|
|
6
|
+
export declare const random: () => number;
|
|
7
|
+
export declare const createSeededRng: (seed: number) => Rng;
|
|
8
|
+
export declare const withRng: <T>(rng: Rng, fn: () => T) => T;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withRng = exports.createSeededRng = exports.random = exports.getActiveRng = exports.defaultRng = void 0;
|
|
4
|
+
const nativeMathRandom = Math.random.bind(Math);
|
|
5
|
+
exports.defaultRng = {
|
|
6
|
+
next: () => nativeMathRandom(),
|
|
7
|
+
};
|
|
8
|
+
let activeRng = exports.defaultRng;
|
|
9
|
+
const getActiveRng = () => activeRng;
|
|
10
|
+
exports.getActiveRng = getActiveRng;
|
|
11
|
+
const random = () => activeRng.next();
|
|
12
|
+
exports.random = random;
|
|
13
|
+
const createSeededRng = (seed) => {
|
|
14
|
+
let state = seed >>> 0;
|
|
15
|
+
return {
|
|
16
|
+
next() {
|
|
17
|
+
state = (state + 0x6d2b79f5) >>> 0;
|
|
18
|
+
let t = state;
|
|
19
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
20
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
21
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
exports.createSeededRng = createSeededRng;
|
|
26
|
+
const withRng = (rng, fn) => {
|
|
27
|
+
const previousRng = activeRng;
|
|
28
|
+
const previousMathRandom = Math.random;
|
|
29
|
+
activeRng = rng;
|
|
30
|
+
Math.random = () => rng.next();
|
|
31
|
+
try {
|
|
32
|
+
return fn();
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
activeRng = previousRng;
|
|
36
|
+
Math.random = previousMathRandom;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
exports.withRng = withRng;
|
|
40
|
+
//# sourceMappingURL=rng.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rng.js","sourceRoot":"","sources":["../../src/services/rng.ts"],"names":[],"mappings":";;;AAaA,MAAM,gBAAgB,GAAiB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEjD,QAAA,UAAU,GAAQ;IAC9B,IAAI,EAAE,GAAG,EAAE,CAAC,gBAAgB,EAAE;CAC9B,CAAC;AAEF,IAAI,SAAS,GAAQ,kBAAU,CAAC;AAEzB,MAAM,YAAY,GAAG,GAAQ,EAAE,CAAC,SAAS,CAAC;AAApC,QAAA,YAAY,gBAAwB;AAG1C,MAAM,MAAM,GAAG,GAAW,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AAAxC,QAAA,MAAM,UAAkC;AAM9C,MAAM,eAAe,GAAG,CAAC,IAAY,EAAO,EAAE;IACpD,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC;IACvB,OAAO;QACN,IAAI;YACH,KAAK,GAAG,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,KAAK,CAAC;YACd,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACrC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,UAAU,CAAC;QAC9C,CAAC;KACD,CAAC;AACH,CAAC,CAAC;AAXW,QAAA,eAAe,mBAW1B;AAMK,MAAM,OAAO,GAAG,CAAI,GAAQ,EAAE,EAAW,EAAK,EAAE;IACtD,MAAM,WAAW,GAAG,SAAS,CAAC;IAC9B,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,CAAC;IACvC,SAAS,GAAG,GAAG,CAAC;IAChB,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI;QACH,OAAO,EAAE,EAAE,CAAC;KACZ;YAAS;QACT,SAAS,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC;KACjC;AACF,CAAC,CAAC;AAXW,QAAA,OAAO,WAWlB","sourcesContent":["/**\r\n * Pluggable RNG for combat. Default uses native Math.random (Firestone Monte Carlo).\r\n * Seeded RNGs make a single battle reproducible for the full-game / self-play env.\r\n *\r\n * During {@link withRng}, Math.random is temporarily redirected so existing call sites\r\n * participate without a mass rewrite. Battles are synchronous, so this is safe on one thread.\r\n */\r\n\r\nexport interface Rng {\r\n\t/** Returns a float in [0, 1). */\r\n\tnext(): number;\r\n}\r\n\r\nconst nativeMathRandom: () => number = Math.random.bind(Math);\r\n\r\nexport const defaultRng: Rng = {\r\n\tnext: () => nativeMathRandom(),\r\n};\r\n\r\nlet activeRng: Rng = defaultRng;\r\n\r\nexport const getActiveRng = (): Rng => activeRng;\r\n\r\n/** Uniform float in [0, 1) from the active RNG. */\r\nexport const random = (): number => activeRng.next();\r\n\r\n/**\r\n * Mulberry32 — small, fast, deterministic. Seed is coerced to uint32.\r\n * Same seed always yields the same sequence.\r\n */\r\nexport const createSeededRng = (seed: number): Rng => {\r\n\tlet state = seed >>> 0;\r\n\treturn {\r\n\t\tnext(): number {\r\n\t\t\tstate = (state + 0x6d2b79f5) >>> 0;\r\n\t\t\tlet t = state;\r\n\t\t\tt = Math.imul(t ^ (t >>> 15), t | 1);\r\n\t\t\tt ^= t + Math.imul(t ^ (t >>> 7), t | 61);\r\n\t\t\treturn ((t ^ (t >>> 14)) >>> 0) / 4294967296;\r\n\t\t},\r\n\t};\r\n};\r\n\r\n/**\r\n * Run `fn` with `rng` as the active source of randomness (including Math.random).\r\n * Restores the previous RNG even if `fn` throws.\r\n */\r\nexport const withRng = <T>(rng: Rng, fn: () => T): T => {\r\n\tconst previousRng = activeRng;\r\n\tconst previousMathRandom = Math.random;\r\n\tactiveRng = rng;\r\n\tMath.random = () => rng.next();\r\n\ttry {\r\n\t\treturn fn();\r\n\t} finally {\r\n\t\tactiveRng = previousRng;\r\n\t\tMath.random = previousMathRandom;\r\n\t}\r\n};\r\n"]}
|
package/dist/services/utils.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findLast = exports.shuffleArray = exports.pickMultipleRandomDifferent = exports.decode = exports.encode = exports.pickRandomHighestHealth = exports.pickRandomHighestAttack = exports.pickRandomLowestAttack = exports.pickRandomLowestHealth = exports.pickMultipleRandomAlive = exports.pickRandomAlive = exports.pickMultipleRandom = exports.pickRandom = exports.sleep = exports.partitionArray = exports.groupByFunction = void 0;
|
|
4
4
|
const debug_state_1 = require("../debug-state");
|
|
5
|
+
const rng_1 = require("./rng");
|
|
5
6
|
function partitionArray(array, partitionSize) {
|
|
6
7
|
const workingCopy = [...array];
|
|
7
8
|
const result = [];
|
|
@@ -46,7 +47,7 @@ function pickRandom(array, sourceEntity) {
|
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
|
-
return array[Math.floor(
|
|
50
|
+
return array[Math.floor((0, rng_1.random)() * array.length)];
|
|
50
51
|
}
|
|
51
52
|
exports.pickRandom = pickRandom;
|
|
52
53
|
const pickMultipleRandom = (array, quantity) => {
|
|
@@ -132,7 +133,7 @@ const shuffleArray = (array) => {
|
|
|
132
133
|
let currentIndex = array.length;
|
|
133
134
|
let randomIndex = 0;
|
|
134
135
|
while (currentIndex != 0) {
|
|
135
|
-
randomIndex = Math.floor(
|
|
136
|
+
randomIndex = Math.floor((0, rng_1.random)() * currentIndex);
|
|
136
137
|
currentIndex--;
|
|
137
138
|
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
|
|
138
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/services/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { BoardTrinket } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { debugState } from '../debug-state';\r\n\r\nfunction partitionArray<T>(array: readonly T[], partitionSize: number): readonly T[][] {\r\n\tconst workingCopy: T[] = [...array];\r\n\tconst result: T[][] = [];\r\n\twhile (workingCopy.length) {\r\n\t\tresult.push(workingCopy.splice(0, partitionSize));\r\n\t}\r\n\treturn result;\r\n}\r\n\r\nasync function sleep(ms) {\r\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport const groupByFunction =\r\n\t<T>(keyExtractor: (obj: T) => string | number) =>\r\n\t(array: readonly T[]): { [key: string]: readonly T[] } => {\r\n\t\treturn (array ?? []).reduce((objectsByKeyValue, obj) => {\r\n\t\t\tconst value = keyExtractor(obj);\r\n\t\t\tobjectsByKeyValue[value] = objectsByKeyValue[value] ?? [];\r\n\t\t\t// Using push instead of concat is thousands of times faster on big arrays\r\n\t\t\tobjectsByKeyValue[value].push(obj);\r\n\t\t\treturn objectsByKeyValue;\r\n\t\t}, {});\r\n\t};\r\n\r\nexport { partitionArray, sleep };\r\n\r\nexport function pickRandom<T>(array: readonly T[]): T;\r\nexport function pickRandom<T extends BoardEntity>(\r\n\tarray: readonly T[],\r\n\tsourceEntity: BoardEntity | BoardSecret | BoardTrinket,\r\n): T;\r\nexport function pickRandom<T>(array: readonly T[], sourceEntity?: BoardEntity | BoardSecret | BoardTrinket): T {\r\n\tif (!array?.length) {\r\n\t\treturn null;\r\n\t}\r\n\tif (\r\n\t\tsourceEntity &&\r\n\t\tdebugState.active &&\r\n\t\tarray.length > 0 &&\r\n\t\ttypeof array[0] === 'object' &&\r\n\t\tarray[0] != null &&\r\n\t\t'entityId' in array[0]\r\n\t) {\r\n\t\tconst forced = debugState.forcedRandomPicks.find((p) => debugState.isCorrectEntity(p.source, sourceEntity));\r\n\t\tif (forced) {\r\n\t\t\tconst match = (array as unknown as BoardEntity[]).find((c) => debugState.isCorrectEntity(forced.target, c));\r\n\t\t\t// Defer consumption when pick has chosenCardId - getRandomMagneticVolumizer will consume (e.g. Apexis Guardian)\r\n\t\t\tif (!forced.chosenCardId) {\r\n\t\t\t\tdebugState.forcedRandomPicks = debugState.forcedRandomPicks.filter((p) => p !== forced);\r\n\t\t\t}\r\n\t\t\tif (match) {\r\n\t\t\t\treturn match as T;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn array[Math.floor(Math.random() * array.length)];\r\n}\r\n\r\nexport const pickMultipleRandom = <T>(array: readonly T[], quantity: number): T[] => {\r\n\tconst picked: T[] = [];\r\n\tfor (let i = 0; i < quantity; i++) {\r\n\t\tconst target = array.filter((e) => !picked.includes(e));\r\n\t\tconst chosenEntity = pickRandom(target);\r\n\t\tif (!!chosenEntity) {\r\n\t\t\tpicked.push(chosenEntity);\r\n\t\t}\r\n\t}\r\n\treturn picked;\r\n};\r\n\r\nexport const pickRandomAlive = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst chosenEntity = pickRandom(targetBoard);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickMultipleRandomAlive = (board: BoardEntity[], quantity: number): BoardEntity[] => {\r\n\tconst picked: BoardEntity[] = [];\r\n\tfor (let i = 0; i < quantity; i++) {\r\n\t\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead).filter((e) => !picked.includes(e));\r\n\t\tconst chosenEntity = pickRandom(targetBoard);\r\n\t\tif (!!chosenEntity) {\r\n\t\t\tpicked.push(chosenEntity);\r\n\t\t}\r\n\t}\r\n\treturn picked;\r\n};\r\n\r\nexport const pickRandomLowestHealth = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst lowestHealth = Math.min(...targetBoard.map((e) => e.health));\r\n\tconst entitiesWithLowestHealth = targetBoard.filter((e) => e.health === lowestHealth);\r\n\tconst chosenEntity = pickRandom(entitiesWithLowestHealth);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickRandomLowestAttack = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst lowestAttack = Math.min(...targetBoard.map((e) => e.attack));\r\n\tconst entitiesWithLowestAttack = targetBoard.filter((e) => e.attack === lowestAttack);\r\n\tconst chosenEntity = pickRandom(entitiesWithLowestAttack);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickRandomHighestAttack = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst highestAttack = Math.max(...targetBoard.map((e) => e.attack));\r\n\tconst entitiesWithHighestAttack = targetBoard.filter((e) => e.attack === highestAttack);\r\n\tconst chosenEntity = pickRandom(entitiesWithHighestAttack);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickRandomHighestHealth = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst highestHealth = Math.max(...targetBoard.map((e) => e.health));\r\n\tconst entitiesWithHighestHealth = targetBoard.filter((e) => e.health === highestHealth);\r\n\tconst chosenEntity = pickRandom(entitiesWithHighestHealth);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const encode = (input: string): string => {\r\n\t// return compressToEncodedURIComponent(input);\r\n\tconst buff = Buffer.from(input, 'utf-8');\r\n\tconst base64 = buff.toString('base64');\r\n\treturn base64;\r\n};\r\n\r\nexport const decode = (base64: string): string => {\r\n\tconst buff = Buffer.from(base64, 'base64');\r\n\tconst str = buff.toString('utf-8');\r\n\treturn str;\r\n};\r\n\r\nexport const pickMultipleRandomDifferent = <T>(list: T[], n: number): T[] => {\r\n\tconst shuffled = shuffleArray([...list]);\r\n\treturn shuffled.slice(0, n);\r\n};\r\n\r\n// https://stackoverflow.com/a/2450976/548701\r\nexport const shuffleArray = <T>(array: T[]): T[] => {\r\n\tlet currentIndex = array.length;\r\n\tlet randomIndex = 0;\r\n\r\n\t// While there remain elements to shuffle...\r\n\twhile (currentIndex != 0) {\r\n\t\t// Pick a remaining element...\r\n\t\trandomIndex = Math.floor(Math.random() * currentIndex);\r\n\t\tcurrentIndex--;\r\n\r\n\t\t// And swap it with the current element.\r\n\t\t[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];\r\n\t}\r\n\r\n\treturn array;\r\n};\r\n\r\nexport const findLast = <T>(\r\n\tarray: readonly T[],\r\n\tpredicate: (value: T, index: number, obj: readonly T[]) => unknown,\r\n): T => {\r\n\tconst filtred = array.filter(predicate);\r\n\tif (!filtred?.length) {\r\n\t\treturn null;\r\n\t}\r\n\tconst last = filtred[filtred.length - 1];\r\n\treturn last;\r\n};\r\n\r\nexport type Mutable<T> = {\r\n\t-readonly [P in keyof T]: T[P];\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/services/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { BoardTrinket } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { debugState } from '../debug-state';\r\nimport { random } from './rng';\r\n\r\nfunction partitionArray<T>(array: readonly T[], partitionSize: number): readonly T[][] {\r\n\tconst workingCopy: T[] = [...array];\r\n\tconst result: T[][] = [];\r\n\twhile (workingCopy.length) {\r\n\t\tresult.push(workingCopy.splice(0, partitionSize));\r\n\t}\r\n\treturn result;\r\n}\r\n\r\nasync function sleep(ms) {\r\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport const groupByFunction =\r\n\t<T>(keyExtractor: (obj: T) => string | number) =>\r\n\t(array: readonly T[]): { [key: string]: readonly T[] } => {\r\n\t\treturn (array ?? []).reduce((objectsByKeyValue, obj) => {\r\n\t\t\tconst value = keyExtractor(obj);\r\n\t\t\tobjectsByKeyValue[value] = objectsByKeyValue[value] ?? [];\r\n\t\t\t// Using push instead of concat is thousands of times faster on big arrays\r\n\t\t\tobjectsByKeyValue[value].push(obj);\r\n\t\t\treturn objectsByKeyValue;\r\n\t\t}, {});\r\n\t};\r\n\r\nexport { partitionArray, sleep };\r\n\r\nexport function pickRandom<T>(array: readonly T[]): T;\r\nexport function pickRandom<T extends BoardEntity>(\r\n\tarray: readonly T[],\r\n\tsourceEntity: BoardEntity | BoardSecret | BoardTrinket,\r\n): T;\r\nexport function pickRandom<T>(array: readonly T[], sourceEntity?: BoardEntity | BoardSecret | BoardTrinket): T {\r\n\tif (!array?.length) {\r\n\t\treturn null;\r\n\t}\r\n\tif (\r\n\t\tsourceEntity &&\r\n\t\tdebugState.active &&\r\n\t\tarray.length > 0 &&\r\n\t\ttypeof array[0] === 'object' &&\r\n\t\tarray[0] != null &&\r\n\t\t'entityId' in array[0]\r\n\t) {\r\n\t\tconst forced = debugState.forcedRandomPicks.find((p) => debugState.isCorrectEntity(p.source, sourceEntity));\r\n\t\tif (forced) {\r\n\t\t\tconst match = (array as unknown as BoardEntity[]).find((c) => debugState.isCorrectEntity(forced.target, c));\r\n\t\t\t// Defer consumption when pick has chosenCardId - getRandomMagneticVolumizer will consume (e.g. Apexis Guardian)\r\n\t\t\tif (!forced.chosenCardId) {\r\n\t\t\t\tdebugState.forcedRandomPicks = debugState.forcedRandomPicks.filter((p) => p !== forced);\r\n\t\t\t}\r\n\t\t\tif (match) {\r\n\t\t\t\treturn match as T;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn array[Math.floor(random() * array.length)];\r\n}\r\n\r\nexport const pickMultipleRandom = <T>(array: readonly T[], quantity: number): T[] => {\r\n\tconst picked: T[] = [];\r\n\tfor (let i = 0; i < quantity; i++) {\r\n\t\tconst target = array.filter((e) => !picked.includes(e));\r\n\t\tconst chosenEntity = pickRandom(target);\r\n\t\tif (!!chosenEntity) {\r\n\t\t\tpicked.push(chosenEntity);\r\n\t\t}\r\n\t}\r\n\treturn picked;\r\n};\r\n\r\nexport const pickRandomAlive = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst chosenEntity = pickRandom(targetBoard);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickMultipleRandomAlive = (board: BoardEntity[], quantity: number): BoardEntity[] => {\r\n\tconst picked: BoardEntity[] = [];\r\n\tfor (let i = 0; i < quantity; i++) {\r\n\t\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead).filter((e) => !picked.includes(e));\r\n\t\tconst chosenEntity = pickRandom(targetBoard);\r\n\t\tif (!!chosenEntity) {\r\n\t\t\tpicked.push(chosenEntity);\r\n\t\t}\r\n\t}\r\n\treturn picked;\r\n};\r\n\r\nexport const pickRandomLowestHealth = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst lowestHealth = Math.min(...targetBoard.map((e) => e.health));\r\n\tconst entitiesWithLowestHealth = targetBoard.filter((e) => e.health === lowestHealth);\r\n\tconst chosenEntity = pickRandom(entitiesWithLowestHealth);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickRandomLowestAttack = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst lowestAttack = Math.min(...targetBoard.map((e) => e.attack));\r\n\tconst entitiesWithLowestAttack = targetBoard.filter((e) => e.attack === lowestAttack);\r\n\tconst chosenEntity = pickRandom(entitiesWithLowestAttack);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickRandomHighestAttack = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst highestAttack = Math.max(...targetBoard.map((e) => e.attack));\r\n\tconst entitiesWithHighestAttack = targetBoard.filter((e) => e.attack === highestAttack);\r\n\tconst chosenEntity = pickRandom(entitiesWithHighestAttack);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const pickRandomHighestHealth = (board: BoardEntity[]): BoardEntity => {\r\n\tconst targetBoard = board.filter((e) => e.health > 0 && !e.definitelyDead);\r\n\tconst highestHealth = Math.max(...targetBoard.map((e) => e.health));\r\n\tconst entitiesWithHighestHealth = targetBoard.filter((e) => e.health === highestHealth);\r\n\tconst chosenEntity = pickRandom(entitiesWithHighestHealth);\r\n\treturn chosenEntity;\r\n};\r\n\r\nexport const encode = (input: string): string => {\r\n\t// return compressToEncodedURIComponent(input);\r\n\tconst buff = Buffer.from(input, 'utf-8');\r\n\tconst base64 = buff.toString('base64');\r\n\treturn base64;\r\n};\r\n\r\nexport const decode = (base64: string): string => {\r\n\tconst buff = Buffer.from(base64, 'base64');\r\n\tconst str = buff.toString('utf-8');\r\n\treturn str;\r\n};\r\n\r\nexport const pickMultipleRandomDifferent = <T>(list: T[], n: number): T[] => {\r\n\tconst shuffled = shuffleArray([...list]);\r\n\treturn shuffled.slice(0, n);\r\n};\r\n\r\n// https://stackoverflow.com/a/2450976/548701\r\nexport const shuffleArray = <T>(array: T[]): T[] => {\r\n\tlet currentIndex = array.length;\r\n\tlet randomIndex = 0;\r\n\r\n\t// While there remain elements to shuffle...\r\n\twhile (currentIndex != 0) {\r\n\t\t// Pick a remaining element...\r\n\t\trandomIndex = Math.floor(random() * currentIndex);\r\n\t\tcurrentIndex--;\r\n\r\n\t\t// And swap it with the current element.\r\n\t\t[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];\r\n\t}\r\n\r\n\treturn array;\r\n};\r\n\r\nexport const findLast = <T>(\r\n\tarray: readonly T[],\r\n\tpredicate: (value: T, index: number, obj: readonly T[]) => unknown,\r\n): T => {\r\n\tconst filtred = array.filter(predicate);\r\n\tif (!filtred?.length) {\r\n\t\treturn null;\r\n\t}\r\n\tconst last = filtred[filtred.length - 1];\r\n\treturn last;\r\n};\r\n\r\nexport type Mutable<T> = {\r\n\t-readonly [P in keyof T]: T[P];\r\n};\r\n"]}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { AllCardsService } from '@firestone-hs/reference-data';
|
|
2
2
|
import { BgsBattleInfo } from './bgs-battle-info';
|
|
3
3
|
import { CardsData } from './cards/cards-data';
|
|
4
|
+
import { Rng } from './services/rng';
|
|
4
5
|
import { SimulationResult } from './simulation-result';
|
|
6
|
+
import { SingleSimulationResult } from './single-simulation-result';
|
|
5
7
|
export { isValidDeathrattleEnchantment } from './simulation/deathrattle-utils';
|
|
8
|
+
export { createSeededRng, defaultRng, getActiveRng, random, withRng } from './services/rng';
|
|
9
|
+
export type { Rng } from './services/rng';
|
|
6
10
|
export declare const assignCards: (cards: AllCardsService) => void;
|
|
11
|
+
export interface SimulateSingleCombatOptions {
|
|
12
|
+
readonly seed?: number;
|
|
13
|
+
readonly rng?: Rng;
|
|
14
|
+
readonly includeSpectator?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const simulateSingleCombat: (battleInput: BgsBattleInfo, cards: AllCardsService, cardsData: CardsData, options?: SimulateSingleCombatOptions) => SingleSimulationResult;
|
|
7
17
|
declare const _default: (event: any) => Promise<any>;
|
|
8
18
|
export default _default;
|
|
9
19
|
export declare const simulateBattle: (battleInput: BgsBattleInfo, cards: AllCardsService, cardsData: CardsData) => Generator<SimulationResult, SimulationResult, void>;
|