@firestone-hs/simulate-bgs-battle 1.1.693 → 1.1.694
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 -1
- package/dist/bgs-battle-info.js.map +1 -1
- package/dist/cards/card.interface.d.ts +5 -1
- package/dist/cards/card.interface.js +3 -1
- package/dist/cards/card.interface.js.map +1 -1
- package/dist/cards/cards-data.d.ts +1 -1
- package/dist/cards/cards-data.js +16 -1
- package/dist/cards/cards-data.js.map +1 -1
- package/dist/cards/impl/_card-mappings.js +4 -0
- package/dist/cards/impl/_card-mappings.js.map +1 -1
- package/dist/cards/impl/minion/apexis-guardian.js +8 -2
- package/dist/cards/impl/minion/apexis-guardian.js.map +1 -1
- package/dist/cards/impl/minion/blue-volumizer.js +3 -1
- package/dist/cards/impl/minion/blue-volumizer.js.map +1 -1
- package/dist/cards/impl/minion/gleaming-trader.js +5 -3
- package/dist/cards/impl/minion/gleaming-trader.js.map +1 -1
- package/dist/cards/impl/minion/grease-bot.js +4 -2
- package/dist/cards/impl/minion/grease-bot.js.map +1 -1
- package/dist/cards/impl/minion/green-volumizer.js +3 -1
- package/dist/cards/impl/minion/green-volumizer.js.map +1 -1
- package/dist/cards/impl/minion/icesnarl-the-mighty.d.ts +2 -0
- package/dist/cards/impl/minion/icesnarl-the-mighty.js +15 -0
- package/dist/cards/impl/minion/icesnarl-the-mighty.js.map +1 -0
- package/dist/cards/impl/minion/polarizing-beatboxer.d.ts +2 -0
- package/dist/cards/impl/minion/polarizing-beatboxer.js +18 -0
- package/dist/cards/impl/minion/polarizing-beatboxer.js.map +1 -0
- package/dist/cards/impl/minion/red-volumizer.js +3 -1
- package/dist/cards/impl/minion/red-volumizer.js.map +1 -1
- package/dist/cards/impl/minion/stalwart-kodo.d.ts +2 -2
- package/dist/cards/impl/minion/stalwart-kodo.js +1 -1
- package/dist/cards/impl/minion/stalwart-kodo.js.map +1 -1
- package/dist/cards/impl/minion/timewarped-grease-bot.js +4 -2
- package/dist/cards/impl/minion/timewarped-grease-bot.js.map +1 -1
- package/dist/cards/impl/minion/timewarped-probius.d.ts +2 -2
- package/dist/cards/impl/minion/timewarped-probius.js +1 -1
- package/dist/cards/impl/minion/timewarped-probius.js.map +1 -1
- package/dist/cards/impl/minion/timewarped-wargear.d.ts +2 -2
- package/dist/cards/impl/minion/timewarped-wargear.js +1 -1
- package/dist/cards/impl/minion/timewarped-wargear.js.map +1 -1
- package/dist/cards/impl/trinket/divine-signet.js +1 -1
- package/dist/cards/impl/trinket/divine-signet.js.map +1 -1
- package/dist/debug-state.d.ts +2 -0
- package/dist/debug-state.js.map +1 -1
- package/dist/keywords/divine-shield.js +32 -28
- package/dist/keywords/divine-shield.js.map +1 -1
- package/dist/services/utils.js +3 -1
- package/dist/services/utils.js.map +1 -1
- package/dist/simulate-bgs-battle.js +6 -8
- package/dist/simulate-bgs-battle.js.map +1 -1
- package/dist/simulation/add-minion-to-board.d.ts +2 -2
- package/dist/simulation/add-minion-to-board.js +3 -12
- package/dist/simulation/add-minion-to-board.js.map +1 -1
- package/dist/simulation/attack.js.map +1 -1
- package/dist/simulation/deathrattle-effects.js +0 -8
- package/dist/simulation/deathrattle-effects.js.map +1 -1
- package/dist/simulation/magnetize.d.ts +3 -1
- package/dist/simulation/magnetize.js +22 -5
- package/dist/simulation/magnetize.js.map +1 -1
- package/dist/simulation/spawns.js +2 -1
- package/dist/simulation/spawns.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,8 +5,10 @@ const utils_1 = require("../../../utils");
|
|
|
5
5
|
exports.TimewarpedGreaseBot = {
|
|
6
6
|
cardIds: ["BG34_Giant_656", "BG34_Giant_656_G"],
|
|
7
7
|
onDivineShieldUpdated: (minion, input) => {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
if (!input.newValue) {
|
|
9
|
+
const mult = minion.cardId === "BG34_Giant_656_G" ? 2 : 1;
|
|
10
|
+
(0, utils_1.addStatsToBoard)(input.target, input.board, input.hero, 3 * mult, 3 * mult, input.gameState);
|
|
11
|
+
}
|
|
10
12
|
},
|
|
11
13
|
};
|
|
12
14
|
//# sourceMappingURL=timewarped-grease-bot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timewarped-grease-bot.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-grease-bot.ts"],"names":[],"mappings":";;;AAGA,0CAAiD;AAGpC,QAAA,mBAAmB,GAA8B;IAC7D,OAAO,EAAE,sCAA0F;IACnG,qBAAqB,EAAE,CAAC,MAAmB,EAAE,KAAiC,EAAE,EAAE;QACjF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,uBAAiD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"timewarped-grease-bot.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-grease-bot.ts"],"names":[],"mappings":";;;AAGA,0CAAiD;AAGpC,QAAA,mBAAmB,GAA8B;IAC7D,OAAO,EAAE,sCAA0F;IACnG,qBAAqB,EAAE,CAAC,MAAmB,EAAE,KAAiC,EAAE,EAAE;QACjF,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;YACpB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,uBAAiD,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpF,IAAA,uBAAe,EAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;SAC5F;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { OnDivineShieldUpdatedInput } from '../../../keywords/divine-shield';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { addStatsToBoard } from '../../../utils';\r\nimport { OnDivineShieldUpdatedCard } from '../../card.interface';\r\n\r\nexport const TimewarpedGreaseBot: OnDivineShieldUpdatedCard = {\r\n\tcardIds: [CardIds.TimewarpedGreaseBot_BG34_Giant_656, CardIds.TimewarpedGreaseBot_BG34_Giant_656_G],\r\n\tonDivineShieldUpdated: (minion: BoardEntity, input: OnDivineShieldUpdatedInput) => {\r\n\t\tif (!input.newValue) {\r\n\t\t\tconst mult = minion.cardId === CardIds.TimewarpedGreaseBot_BG34_Giant_656_G ? 2 : 1;\r\n\t\t\taddStatsToBoard(input.target, input.board, input.hero, 3 * mult, 3 * mult, input.gameState);\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const TimewarpedProbius:
|
|
1
|
+
import { OnAfterMagnetizeSelfCard } from '../../card.interface';
|
|
2
|
+
export declare const TimewarpedProbius: OnAfterMagnetizeSelfCard;
|
|
@@ -6,7 +6,7 @@ const golden_1 = require("../../../simulation/utils/golden");
|
|
|
6
6
|
const utils_1 = require("../../../utils");
|
|
7
7
|
exports.TimewarpedProbius = {
|
|
8
8
|
cardIds: ["BG34_Giant_121", "BG34_Giant_121_G"],
|
|
9
|
-
|
|
9
|
+
onAfterMagnetizeSelf: (entity, input) => {
|
|
10
10
|
if ((0, utils_1.hasCorrectTribe)(input.magnetizeTarget, input.hero, reference_data_1.Race.MECH, input.gameState.anomalies, input.gameState.allCards)) {
|
|
11
11
|
(0, golden_1.makeMinionGolden)(input.magnetizeTarget, entity, input.board, input.hero, input.otherBoard, input.otherHero, input.gameState);
|
|
12
12
|
input.gameState.spectator.registerPowerTarget(entity, input.magnetizeTarget, input.board, input.hero, input.otherHero);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timewarped-probius.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-probius.ts"],"names":[],"mappings":";;;AAAA,iEAAoD;AAIpD,6DAAoE;AACpE,0CAAiD;AAGpC,QAAA,iBAAiB,
|
|
1
|
+
{"version":3,"file":"timewarped-probius.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-probius.ts"],"names":[],"mappings":";;;AAAA,iEAAoD;AAIpD,6DAAoE;AACpE,0CAAiD;AAGpC,QAAA,iBAAiB,GAA6B;IAC1D,OAAO,EAAE,sCAAsF;IAC/F,oBAAoB,EAAE,CAAC,MAAmB,EAAE,KAA4B,EAAE,EAAE;QAC3E,IACC,IAAA,uBAAe,EACd,KAAK,CAAC,eAAe,EACrB,KAAK,CAAC,IAAI,EACV,qBAAI,CAAC,IAAI,EACT,KAAK,CAAC,SAAS,CAAC,SAAS,EACzB,KAAK,CAAC,SAAS,CAAC,QAAQ,CACxB,EACA;YACD,IAAA,yBAAgB,EACf,KAAK,CAAC,eAAe,EACrB,MAAM,EACN,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,SAAS,CACf,CAAC;YACF,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAC5C,MAAM,EACN,KAAK,CAAC,eAAe,EACrB,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,SAAS,CACf,CAAC;SACF;IACF,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 { OnAfterMagnetizeInput } from '../../../simulation/magnetize';\r\nimport { makeMinionGolden } from '../../../simulation/utils/golden';\r\nimport { hasCorrectTribe } from '../../../utils';\r\nimport { OnAfterMagnetizeSelfCard } from '../../card.interface';\r\n\r\nexport const TimewarpedProbius: OnAfterMagnetizeSelfCard = {\r\n\tcardIds: [CardIds.TimewarpedProbius_BG34_Giant_121, CardIds.TimewarpedProbius_BG34_Giant_121_G],\r\n\tonAfterMagnetizeSelf: (entity: BoardEntity, input: OnAfterMagnetizeInput) => {\r\n\t\tif (\r\n\t\t\thasCorrectTribe(\r\n\t\t\t\tinput.magnetizeTarget,\r\n\t\t\t\tinput.hero,\r\n\t\t\t\tRace.MECH,\r\n\t\t\t\tinput.gameState.anomalies,\r\n\t\t\t\tinput.gameState.allCards,\r\n\t\t\t)\r\n\t\t) {\r\n\t\t\tmakeMinionGolden(\r\n\t\t\t\tinput.magnetizeTarget,\r\n\t\t\t\tentity,\r\n\t\t\t\tinput.board,\r\n\t\t\t\tinput.hero,\r\n\t\t\t\tinput.otherBoard,\r\n\t\t\t\tinput.otherHero,\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t\tinput.gameState.spectator.registerPowerTarget(\r\n\t\t\t\tentity,\r\n\t\t\t\tinput.magnetizeTarget,\r\n\t\t\t\tinput.board,\r\n\t\t\t\tinput.hero,\r\n\t\t\t\tinput.otherHero,\r\n\t\t\t);\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const TimewarpedWargear:
|
|
1
|
+
import { OnAfterMagnetizeToSelfCard } from '../../card.interface';
|
|
2
|
+
export declare const TimewarpedWargear: OnAfterMagnetizeToSelfCard;
|
|
@@ -4,7 +4,7 @@ exports.TimewarpedWargear = void 0;
|
|
|
4
4
|
const stats_1 = require("../../../simulation/stats");
|
|
5
5
|
exports.TimewarpedWargear = {
|
|
6
6
|
cardIds: ["BG34_Giant_677", "BG34_Giant_677_G"],
|
|
7
|
-
|
|
7
|
+
onAfterMagnetizeToSelf: (minion, input) => {
|
|
8
8
|
const mult = minion.cardId === "BG34_Giant_677_G" ? 2 : 1;
|
|
9
9
|
(0, stats_1.modifyStats)(input.magnetizeTarget, minion, input.magnetizeTarget.attack * mult, input.magnetizeTarget.health * mult, input.board, input.hero, input.gameState);
|
|
10
10
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timewarped-wargear.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-wargear.ts"],"names":[],"mappings":";;;AAGA,qDAAwD;AAG3C,QAAA,iBAAiB,
|
|
1
|
+
{"version":3,"file":"timewarped-wargear.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/timewarped-wargear.ts"],"names":[],"mappings":";;;AAGA,qDAAwD;AAG3C,QAAA,iBAAiB,GAA+B;IAC5D,OAAO,EAAE,sCAAsF;IAC/F,sBAAsB,EAAE,CAAC,MAAmB,EAAE,KAAgC,EAAE,EAAE;QACjF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,uBAA+C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAElF,IAAA,mBAAW,EACV,KAAK,CAAC,eAAe,EACrB,MAAM,EACN,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,EACnC,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,EACnC,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,SAAS,CACf,CAAC;IACH,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { OnAfterMagnetizeSelfInput } from '../../../simulation/magnetize';\r\nimport { modifyStats } from '../../../simulation/stats';\r\nimport { OnAfterMagnetizeToSelfCard } from '../../card.interface';\r\n\r\nexport const TimewarpedWargear: OnAfterMagnetizeToSelfCard = {\r\n\tcardIds: [CardIds.TimewarpedWargear_BG34_Giant_677, CardIds.TimewarpedWargear_BG34_Giant_677_G],\r\n\tonAfterMagnetizeToSelf: (minion: BoardEntity, input: OnAfterMagnetizeSelfInput) => {\r\n\t\tconst mult = minion.cardId === CardIds.TimewarpedWargear_BG34_Giant_677_G ? 2 : 1;\r\n\t\t// Never sure whether to use setEntityStats or modifyStats here (ie aura reapply or not)\r\n\t\tmodifyStats(\r\n\t\t\tinput.magnetizeTarget,\r\n\t\t\tminion,\r\n\t\t\tinput.magnetizeTarget.attack * mult,\r\n\t\t\tinput.magnetizeTarget.health * mult,\r\n\t\t\tinput.board,\r\n\t\t\tinput.hero,\r\n\t\t\tinput.gameState,\r\n\t\t);\r\n\t},\r\n};\r\n"]}
|
|
@@ -5,7 +5,7 @@ const cards_in_hand_1 = require("../../../simulation/cards-in-hand");
|
|
|
5
5
|
exports.DivineSignet = {
|
|
6
6
|
cardIds: ["BG32_MagicItem_171"],
|
|
7
7
|
onDivineShieldUpdated: (trinket, input) => {
|
|
8
|
-
if (trinket.scriptDataNum1 > 0) {
|
|
8
|
+
if (!input.newValue && trinket.scriptDataNum1 > 0) {
|
|
9
9
|
(0, cards_in_hand_1.addCardsInHand)(input.hero, input.board, [input.gameState.cardsData.getRandomTavernSpell()], input.gameState);
|
|
10
10
|
trinket.scriptDataNum1--;
|
|
11
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"divine-signet.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/divine-signet.ts"],"names":[],"mappings":";;;AAGA,qEAAmE;AAGtD,QAAA,YAAY,GAA8B;IACtD,OAAO,EAAE,sBAAyC;IAClD,qBAAqB,EAAE,CAAC,OAAqB,EAAE,KAAiC,EAAE,EAAE;QACnF,IAAI,OAAO,CAAC,cAAc,GAAG,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"divine-signet.js","sourceRoot":"","sources":["../../../../src/cards/impl/trinket/divine-signet.ts"],"names":[],"mappings":";;;AAGA,qEAAmE;AAGtD,QAAA,YAAY,GAA8B;IACtD,OAAO,EAAE,sBAAyC;IAClD,qBAAqB,EAAE,CAAC,OAAqB,EAAE,KAAiC,EAAE,EAAE;QACnF,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,cAAc,GAAG,CAAC,EAAE;YAClD,IAAA,8BAAc,EACb,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,KAAK,EACX,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC,EAClD,KAAK,CAAC,SAAS,CACf,CAAC;YACF,OAAO,CAAC,cAAc,EAAE,CAAC;SACzB;IACF,CAAC;CACD,CAAC","sourcesContent":["import { BoardTrinket } from '../../../bgs-player-entity';\r\nimport { OnDivineShieldUpdatedInput } from '../../../keywords/divine-shield';\r\nimport { CardIds } from '../../../services/card-ids';\r\nimport { addCardsInHand } from '../../../simulation/cards-in-hand';\r\nimport { OnDivineShieldUpdatedCard } from '../../card.interface';\r\n\r\nexport const DivineSignet: OnDivineShieldUpdatedCard = {\r\n\tcardIds: [CardIds.DivineSignet_BG32_MagicItem_171],\r\n\tonDivineShieldUpdated: (trinket: BoardTrinket, input: OnDivineShieldUpdatedInput) => {\r\n\t\tif (!input.newValue && trinket.scriptDataNum1 > 0) {\r\n\t\t\taddCardsInHand(\r\n\t\t\t\tinput.hero,\r\n\t\t\t\tinput.board,\r\n\t\t\t\t[input.gameState.cardsData.getRandomTavernSpell()],\r\n\t\t\t\tinput.gameState,\r\n\t\t\t);\r\n\t\t\ttrinket.scriptDataNum1--;\r\n\t\t}\r\n\t},\r\n};\r\n"]}
|
package/dist/debug-state.d.ts
CHANGED
|
@@ -13,11 +13,13 @@ export declare const debugState: {
|
|
|
13
13
|
forcedRandomPicks: {
|
|
14
14
|
source: ForcedFaceOffEntity;
|
|
15
15
|
target: ForcedFaceOffEntity;
|
|
16
|
+
chosenCardId?: string;
|
|
16
17
|
}[];
|
|
17
18
|
isCorrectEntity: (proposedEntity: ForcedFaceOffEntity, actualEntity: BoardEntity) => boolean;
|
|
18
19
|
forcedRandomPicksBase: {
|
|
19
20
|
source: ForcedFaceOffEntity;
|
|
20
21
|
target: ForcedFaceOffEntity;
|
|
22
|
+
chosenCardId?: string;
|
|
21
23
|
}[];
|
|
22
24
|
onBattleStart: () => void;
|
|
23
25
|
};
|
package/dist/debug-state.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-state.js","sourceRoot":"","sources":["../src/debug-state.ts"],"names":[],"mappings":";;;AAEa,QAAA,UAAU,GAAG;IACzB,MAAM,EAAE,KAAK;IACb,qBAAqB,EAAE,IAAqB;IAC5C,aAAa,EAAE,EAAwE;IACvF,iBAAiB,EAAE,EAAwE;IAE3F,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"debug-state.js","sourceRoot":"","sources":["../src/debug-state.ts"],"names":[],"mappings":";;;AAEa,QAAA,UAAU,GAAG;IACzB,MAAM,EAAE,KAAK;IACb,qBAAqB,EAAE,IAAqB;IAC5C,aAAa,EAAE,EAAwE;IACvF,iBAAiB,EAAE,EAAwE;IAE3F,iBAAiB,EAAE,EAA2F;IAC9G,eAAe,EAAE,CAAC,cAAmC,EAAE,YAAyB,EAAW,EAAE;QAC5F,IAAI,cAAc,CAAC,QAAQ,EAAE;YAC5B,OAAO,cAAc,CAAC,QAAQ,KAAK,YAAY,CAAC,QAAQ,CAAC;SACzD;QACD,IAAI,cAAc,CAAC,MAAM,EAAE;YAC1B,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,CAAC;YAClE,IAAI,cAAc,CAAC,MAAM,IAAI,IAAI,IAAI,cAAc,CAAC,MAAM,IAAI,IAAI,EAAE;gBACnE,OAAO,WAAW,IAAI,cAAc,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,CAAC;aACrH;YACD,OAAO,WAAW,CAAC;SACnB;QACD,OAAO,CACN,cAAc,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM;YAC7C,cAAc,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,CAC7C,CAAC;IACH,CAAC;IACD,qBAAqB,EAAE,EAA2F;IAClH,aAAa,EAAE,GAAG,EAAE;QACnB,kBAAU,CAAC,aAAa,GAAG,CAAC,GAAG,kBAAU,CAAC,iBAAiB,CAAC,CAAC;QAC7D,kBAAU,CAAC,iBAAiB,GAAG,CAAC,GAAG,kBAAU,CAAC,qBAAqB,CAAC,CAAC;IACtE,CAAC;CACD,CAAC","sourcesContent":["import { BoardEntity } from './board-entity';\n\nexport const debugState = {\n\tactive: false,\n\tforcedCurrentAttacker: null as number | null,\n\tforcedFaceOff: [] as { attacker: ForcedFaceOffEntity; defender: ForcedFaceOffEntity }[],\n\tforcedFaceOffBase: [] as { attacker: ForcedFaceOffEntity; defender: ForcedFaceOffEntity }[],\n\t/** Forced random picks: source -> target. Matched by source entity (like face-offs match by attacker). Optional chosenCardId for card-pool picks (e.g. Apexis Guardian Volumizer). */\n\tforcedRandomPicks: [] as { source: ForcedFaceOffEntity; target: ForcedFaceOffEntity; chosenCardId?: string }[],\n\tisCorrectEntity: (proposedEntity: ForcedFaceOffEntity, actualEntity: BoardEntity): boolean => {\n\t\tif (proposedEntity.entityId) {\n\t\t\treturn proposedEntity.entityId === actualEntity.entityId;\n\t\t}\n\t\tif (proposedEntity.cardId) {\n\t\t\tconst cardMatches = proposedEntity.cardId === actualEntity.cardId;\n\t\t\tif (proposedEntity.attack != null && proposedEntity.health != null) {\n\t\t\t\treturn cardMatches && proposedEntity.attack === actualEntity.attack && proposedEntity.health === actualEntity.health;\n\t\t\t}\n\t\t\treturn cardMatches;\n\t\t}\n\t\treturn (\n\t\t\tproposedEntity.attack === actualEntity.attack &&\n\t\t\tproposedEntity.health === actualEntity.health\n\t\t);\n\t},\n\tforcedRandomPicksBase: [] as { source: ForcedFaceOffEntity; target: ForcedFaceOffEntity; chosenCardId?: string }[],\n\tonBattleStart: () => {\n\t\tdebugState.forcedFaceOff = [...debugState.forcedFaceOffBase];\n\t\tdebugState.forcedRandomPicks = [...debugState.forcedRandomPicksBase];\n\t},\n};\n\nexport interface ForcedFaceOffEntity {\n\tentityId?: number;\n\tcardId?: string;\n\tattack?: number;\n\thealth?: number;\n}\n"]}
|
|
@@ -9,6 +9,10 @@ const stats_1 = require("../simulation/stats");
|
|
|
9
9
|
const utils_2 = require("../utils");
|
|
10
10
|
const updateDivineShield = (entity, board, hero, otherHero, newValue, gameState) => {
|
|
11
11
|
var _a;
|
|
12
|
+
if (newValue === entity.divineShield) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const previousValue = entity.divineShield;
|
|
12
16
|
entity.hadDivineShield = newValue || entity.divineShield || entity.hadDivineShield;
|
|
13
17
|
if (entity.strongDivineShield && newValue === false) {
|
|
14
18
|
entity.strongDivineShield = false;
|
|
@@ -28,6 +32,34 @@ const updateDivineShield = (entity, board, hero, otherHero, newValue, gameState)
|
|
|
28
32
|
12 * boardForDrake.filter((e) => e.cardId === "BG25_043_G").length;
|
|
29
33
|
entity.attack -= statsBonus;
|
|
30
34
|
}
|
|
35
|
+
for (const trinket of (_a = hero.trinkets) !== null && _a !== void 0 ? _a : []) {
|
|
36
|
+
const onDivineShieldUpdatedImpl = _card_mappings_1.cardMappings[trinket.cardId];
|
|
37
|
+
if ((0, card_interface_1.hasOnDivineShieldUpdated)(onDivineShieldUpdatedImpl)) {
|
|
38
|
+
onDivineShieldUpdatedImpl.onDivineShieldUpdated(trinket, {
|
|
39
|
+
board: board,
|
|
40
|
+
hero: hero,
|
|
41
|
+
otherHero: otherHero,
|
|
42
|
+
gameState: gameState,
|
|
43
|
+
target: entity,
|
|
44
|
+
newValue: newValue,
|
|
45
|
+
previousValue: previousValue,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const boardEntity of board) {
|
|
50
|
+
const onDivineShieldUpdatedImpl = _card_mappings_1.cardMappings[boardEntity.cardId];
|
|
51
|
+
if ((0, card_interface_1.hasOnDivineShieldUpdated)(onDivineShieldUpdatedImpl)) {
|
|
52
|
+
onDivineShieldUpdatedImpl.onDivineShieldUpdated(boardEntity, {
|
|
53
|
+
board: board,
|
|
54
|
+
hero: hero,
|
|
55
|
+
otherHero: otherHero,
|
|
56
|
+
gameState: gameState,
|
|
57
|
+
target: entity,
|
|
58
|
+
newValue: newValue,
|
|
59
|
+
previousValue: previousValue,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
31
63
|
if (entity.hadDivineShield && !entity.divineShield) {
|
|
32
64
|
const adapter = hero.trinkets
|
|
33
65
|
.filter((t) => t.cardId === "BG30_MagicItem_910")
|
|
@@ -36,34 +68,6 @@ const updateDivineShield = (entity, board, hero, otherHero, newValue, gameState)
|
|
|
36
68
|
(0, exports.updateDivineShield)(entity, board, hero, otherHero, true, gameState);
|
|
37
69
|
adapter.scriptDataNum1--;
|
|
38
70
|
}
|
|
39
|
-
for (const trinket of (_a = hero.trinkets) !== null && _a !== void 0 ? _a : []) {
|
|
40
|
-
const onDivineShieldUpdatedImpl = _card_mappings_1.cardMappings[trinket.cardId];
|
|
41
|
-
if ((0, card_interface_1.hasOnDivineShieldUpdated)(onDivineShieldUpdatedImpl)) {
|
|
42
|
-
onDivineShieldUpdatedImpl.onDivineShieldUpdated(trinket, {
|
|
43
|
-
board: board,
|
|
44
|
-
hero: hero,
|
|
45
|
-
otherHero: otherHero,
|
|
46
|
-
gameState: gameState,
|
|
47
|
-
target: entity,
|
|
48
|
-
newValue: false,
|
|
49
|
-
previousValue: true,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
for (const boardEntity of board) {
|
|
54
|
-
const onDivineShieldUpdatedImpl = _card_mappings_1.cardMappings[boardEntity.cardId];
|
|
55
|
-
if ((0, card_interface_1.hasOnDivineShieldUpdated)(onDivineShieldUpdatedImpl)) {
|
|
56
|
-
onDivineShieldUpdatedImpl.onDivineShieldUpdated(boardEntity, {
|
|
57
|
-
board: board,
|
|
58
|
-
hero: hero,
|
|
59
|
-
otherHero: otherHero,
|
|
60
|
-
gameState: gameState,
|
|
61
|
-
target: entity,
|
|
62
|
-
newValue: false,
|
|
63
|
-
previousValue: true,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
71
|
for (let i = 0; i < board.length; i++) {
|
|
68
72
|
if (board[i].cardId === "ICC_858") {
|
|
69
73
|
(0, stats_1.modifyStats)(board[i], board[i], 2, 0, board, hero, gameState);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"divine-shield.js","sourceRoot":"","sources":["../../src/keywords/divine-shield.ts"],"names":[],"mappings":";;;AAAA,iEAAoD;AAGpD,4DAAmE;AACnE,iEAA4D;AAE5D,6CAA+C;AAE/C,+CAAkD;AAClD,oCAA2C;AAEpC,MAAM,kBAAkB,GAAG,CACjC,MAAmB,EACnB,KAAoB,EACpB,IAAqB,EACrB,SAA0B,EAC1B,QAAiB,EACjB,SAAwB,EACjB,EAAE;;IACT,MAAM,CAAC,eAAe,GAAG,QAAQ,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,eAAe,CAAC;IACnF,IAAI,MAAM,CAAC,kBAAkB,IAAI,QAAQ,KAAK,KAAK,EAAE;QACpD,MAAM,CAAC,kBAAkB,GAAG,KAAK,CAAC;KAClC;SAAM;QACN,MAAM,CAAC,YAAY,GAAG,QAAQ,CAAC;KAC/B;IACD,IAAI,MAAM,CAAC,YAAY,IAAI,QAAQ,EAAE;QACpC,MAAM,aAAa,GAAG,KAAK,CAAC;QAC5B,MAAM,UAAU,GACf,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAiC,CAAC,CAAC,MAAM;YACjF,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAAmC,CAAC,CAAC,MAAM,CAAC;QAEtF,MAAM,CAAC,MAAM,IAAI,UAAU,CAAC;KAC5B;SAAM,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;QAEhC,MAAM,aAAa,GAAG,KAAK,CAAC;QAC5B,MAAM,UAAU,GACf,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,eAAiC,CAAC,CAAC,MAAM;YACjF,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,iBAAmC,CAAC,CAAC,MAAM,CAAC;QACtF,MAAM,CAAC,MAAM,IAAI,UAAU,CAAC;KAC5B;IAGD,IAAI,MAAM,CAAC,eAAe,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ;aAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,yBAA+C,CAAC;aACtE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,CAAC,OAAO,IAAI,IAAA,uBAAe,EAAC,MAAM,EAAE,IAAI,EAAE,qBAAI,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,EAAE;YACnG,IAAA,0BAAkB,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;YACpE,OAAO,CAAC,cAAc,EAAE,CAAC;SACzB;QAED,KAAK,MAAM,OAAO,IAAI,MAAA,IAAI,CAAC,QAAQ,mCAAI,EAAE,EAAE;YAC1C,MAAM,yBAAyB,GAAG,6BAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/D,IAAI,IAAA,yCAAwB,EAAC,yBAAyB,CAAC,EAAE;gBACxD,yBAAyB,CAAC,qBAAqB,CAAC,OAAO,EAAE;oBACxD,KAAK,EAAE,KAAK;oBACZ,IAAI,EAAE,IAAI;oBACV,SAAS,EAAE,SAAS;oBACpB,SAAS,EAAE,SAAS;oBACpB,MAAM,EAAE,MAAM;oBACd,QAAQ,EAAE,KAAK;oBACf,aAAa,EAAE,IAAI;iBACnB,CAAC,CAAC;aACH;SACD;QAED,KAAK,MAAM,WAAW,IAAI,KAAK,EAAE;YAChC,MAAM,yBAAyB,GAAG,6BAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACnE,IAAI,IAAA,yCAAwB,EAAC,yBAAyB,CAAC,EAAE;gBACxD,yBAAyB,CAAC,qBAAqB,CAAC,WAAW,EAAE;oBAC5D,KAAK,EAAE,KAAK;oBACZ,IAAI,EAAE,IAAI;oBACV,SAAS,EAAE,SAAS;oBACpB,SAAS,EAAE,SAAS;oBACpB,MAAM,EAAE,MAAM;oBACd,QAAQ,EAAE,KAAK;oBACf,aAAa,EAAE,IAAI;iBACnB,CAAC,CAAC;aACH;SACD;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,cAAoC,EAAE;gBACxD,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC9D,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;aAUpF;SAsBD;KACD;AACF,CAAC,CAAC;AA3GW,QAAA,kBAAkB,sBA2G7B;AAEK,MAAM,uBAAuB,GAAG,CACtC,MAAmB,EACnB,KAAoB,EACpB,IAAqB,EACrB,SAA0B,EAC1B,SAAwB,EACjB,EAAE;IACT,MAAM,iBAAiB,GAAG,KAAK;SAC7B,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;SACxC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAClE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;QACjC,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,iBAAiB,CAAC,CAAC;QAC7C,IAAA,0BAAkB,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACpE,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;KAC3E;AACF,CAAC,CAAC;AAfW,QAAA,uBAAuB,2BAelC;AAEK,MAAM,kCAAkC,GAAG,CACjD,MAAmB,EACnB,KAAoB,EACpB,IAAqB,EACrB,QAAgB,EAChB,SAA0B,EAC1B,SAAwB,EACjB,EAAE;IACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE;QAC1D,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACtE,SAAS,CAAC,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;KAC7E;AACF,CAAC,CAAC;AAZW,QAAA,kCAAkC,sCAY7C","sourcesContent":["import { Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnDivineShieldUpdated } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickRandom } from '../services/utils';\r\nimport { FullGameState } from '../simulation/internal-game-state';\r\nimport { modifyStats } from '../simulation/stats';\r\nimport { hasCorrectTribe } from '../utils';\r\n\r\nexport const updateDivineShield = (\r\n\tentity: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tnewValue: boolean,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tentity.hadDivineShield = newValue || entity.divineShield || entity.hadDivineShield;\r\n\tif (entity.strongDivineShield && newValue === false) {\r\n\t\tentity.strongDivineShield = false;\r\n\t} else {\r\n\t\tentity.divineShield = newValue;\r\n\t}\r\n\tif (entity.divineShield && newValue) {\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t6 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t12 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\t// Don't trigger all \"on attack changed\" effects, since it's an aura\r\n\t\tentity.attack += statsBonus;\r\n\t} else if (!entity.divineShield) {\r\n\t\t// Also consider itself\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t6 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t12 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\tentity.attack -= statsBonus;\r\n\t}\r\n\r\n\t// Lost divine shield\r\n\tif (entity.hadDivineShield && !entity.divineShield) {\r\n\t\tconst adapter = hero.trinkets\r\n\t\t\t.filter((t) => t.cardId === CardIds.MechagonAdapter_BG30_MagicItem_910)\r\n\t\t\t.filter((t) => t.scriptDataNum1 > 0)[0];\r\n\t\tif (!!adapter && hasCorrectTribe(entity, hero, Race.MECH, gameState.anomalies, gameState.allCards)) {\r\n\t\t\tupdateDivineShield(entity, board, hero, otherHero, true, gameState);\r\n\t\t\tadapter.scriptDataNum1--;\r\n\t\t}\r\n\r\n\t\tfor (const trinket of hero.trinkets ?? []) {\r\n\t\t\tconst onDivineShieldUpdatedImpl = cardMappings[trinket.cardId];\r\n\t\t\tif (hasOnDivineShieldUpdated(onDivineShieldUpdatedImpl)) {\r\n\t\t\t\tonDivineShieldUpdatedImpl.onDivineShieldUpdated(trinket, {\r\n\t\t\t\t\tboard: board,\r\n\t\t\t\t\thero: hero,\r\n\t\t\t\t\totherHero: otherHero,\r\n\t\t\t\t\tgameState: gameState,\r\n\t\t\t\t\ttarget: entity,\r\n\t\t\t\t\tnewValue: false,\r\n\t\t\t\t\tpreviousValue: true,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfor (const boardEntity of board) {\r\n\t\t\tconst onDivineShieldUpdatedImpl = cardMappings[boardEntity.cardId];\r\n\t\t\tif (hasOnDivineShieldUpdated(onDivineShieldUpdatedImpl)) {\r\n\t\t\t\tonDivineShieldUpdatedImpl.onDivineShieldUpdated(boardEntity, {\r\n\t\t\t\t\tboard: board,\r\n\t\t\t\t\thero: hero,\r\n\t\t\t\t\totherHero: otherHero,\r\n\t\t\t\t\tgameState: gameState,\r\n\t\t\t\t\ttarget: entity,\r\n\t\t\t\t\tnewValue: false,\r\n\t\t\t\t\tpreviousValue: true,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfor (let i = 0; i < board.length; i++) {\r\n\t\t\tif (board[i].cardId === CardIds.BolvarFireblood_ICC_858) {\r\n\t\t\t\tmodifyStats(board[i], board[i], 2, 0, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t\t// } else if (board[i].cardId === CardIds.BolvarFireblood_TB_BaconUps_047) {\r\n\t\t\t\t// \tmodifyStats(board[i], board[i], 4, 0, board, hero, gameState);\r\n\t\t\t\t// \tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t\t// } else if (board[i].cardId === CardIds.DrakonidEnforcer_BGS_067) {\r\n\t\t\t\t// \tmodifyStats(board[i], board[i], 2, 2, board, hero, gameState);\r\n\t\t\t\t// \tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t\t// } else if (board[i].cardId === CardIds.DrakonidEnforcer_TB_BaconUps_117) {\r\n\t\t\t\t// \tmodifyStats(board[i], board[i], 4, 4, board, hero, gameState);\r\n\t\t\t\t// \tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t}\r\n\t\t\t// } else if (\r\n\t\t\t// \tboard[i].cardId === CardIds.CogworkCopter_BG24_008 ||\r\n\t\t\t// \tboard[i].cardId === CardIds.CogworkCopter_BG24_008_G\r\n\t\t\t// ) {\r\n\t\t\t// When it's the opponent, the game state already contains all the buffs\r\n\t\t\t// if (board[i]?.friendly) {\r\n\t\t\t// \tconst buff = 1; //board[i].cardId === CardIds.CogworkCopter_BG24_008_G ? 2 : 1;\r\n\t\t\t// \tgrantRandomStats(\r\n\t\t\t// \t\tboard[i],\r\n\t\t\t// \t\thero.hand.filter(\r\n\t\t\t// \t\t\t(e) =>\r\n\t\t\t// \t\t\t\tgameState.allCards.getCard(e.cardId).type?.toUpperCase() === CardType[CardType.MINION],\r\n\t\t\t// \t\t),\r\n\t\t\t// \t\thero,\r\n\t\t\t// \t\tbuff,\r\n\t\t\t// \t\tbuff,\r\n\t\t\t// \t\tnull,\r\n\t\t\t// \t\ttrue,\r\n\t\t\t// \t\tgameState,\r\n\t\t\t// \t);\r\n\t\t\t// }\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const grantRandomDivineShield = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst elligibleEntities = board\r\n\t\t.filter((entity) => !entity.divineShield)\r\n\t\t.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\tif (elligibleEntities.length > 0) {\r\n\t\tconst chosen = pickRandom(elligibleEntities);\r\n\t\tupdateDivineShield(chosen, board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, chosen, board, null, null);\r\n\t}\r\n};\r\n\r\nexport const grantDivineShieldToLeftmostMinions = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tquantity: number,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tfor (let i = 0; i < Math.min(quantity, board.length); i++) {\r\n\t\tupdateDivineShield(board[i], board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, board[i], board, null, null);\r\n\t}\r\n};\r\n\r\nexport interface OnDivineShieldUpdatedInput {\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n\ttarget: BoardEntity;\r\n\tnewValue: boolean;\r\n\tpreviousValue: boolean;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"divine-shield.js","sourceRoot":"","sources":["../../src/keywords/divine-shield.ts"],"names":[],"mappings":"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","sourcesContent":["import { Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { hasOnDivineShieldUpdated } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { pickRandom } from '../services/utils';\r\nimport { FullGameState } from '../simulation/internal-game-state';\r\nimport { modifyStats } from '../simulation/stats';\r\nimport { hasCorrectTribe } from '../utils';\r\n\r\nexport const updateDivineShield = (\r\n\tentity: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tnewValue: boolean,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tif (newValue === entity.divineShield) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tconst previousValue = entity.divineShield;\r\n\tentity.hadDivineShield = newValue || entity.divineShield || entity.hadDivineShield;\r\n\tif (entity.strongDivineShield && newValue === false) {\r\n\t\tentity.strongDivineShield = false;\r\n\t} else {\r\n\t\tentity.divineShield = newValue;\r\n\t}\r\n\tif (entity.divineShield && newValue) {\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t6 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t12 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\t// Don't trigger all \"on attack changed\" effects, since it's an aura\r\n\t\tentity.attack += statsBonus;\r\n\t} else if (!entity.divineShield) {\r\n\t\t// Also consider itself\r\n\t\tconst boardForDrake = board;\r\n\t\tconst statsBonus =\r\n\t\t\t6 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043).length +\r\n\t\t\t12 * boardForDrake.filter((e) => e.cardId === CardIds.CyborgDrake_BG25_043_G).length;\r\n\t\tentity.attack -= statsBonus;\r\n\t}\r\n\r\n\tfor (const trinket of hero.trinkets ?? []) {\r\n\t\tconst onDivineShieldUpdatedImpl = cardMappings[trinket.cardId];\r\n\t\tif (hasOnDivineShieldUpdated(onDivineShieldUpdatedImpl)) {\r\n\t\t\tonDivineShieldUpdatedImpl.onDivineShieldUpdated(trinket, {\r\n\t\t\t\tboard: board,\r\n\t\t\t\thero: hero,\r\n\t\t\t\totherHero: otherHero,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t\ttarget: entity,\r\n\t\t\t\tnewValue: newValue,\r\n\t\t\t\tpreviousValue: previousValue,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\tfor (const boardEntity of board) {\r\n\t\tconst onDivineShieldUpdatedImpl = cardMappings[boardEntity.cardId];\r\n\t\tif (hasOnDivineShieldUpdated(onDivineShieldUpdatedImpl)) {\r\n\t\t\tonDivineShieldUpdatedImpl.onDivineShieldUpdated(boardEntity, {\r\n\t\t\t\tboard: board,\r\n\t\t\t\thero: hero,\r\n\t\t\t\totherHero: otherHero,\r\n\t\t\t\tgameState: gameState,\r\n\t\t\t\ttarget: entity,\r\n\t\t\t\tnewValue: newValue,\r\n\t\t\t\tpreviousValue: previousValue,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\t// Lost divine shield\r\n\tif (entity.hadDivineShield && !entity.divineShield) {\r\n\t\tconst adapter = hero.trinkets\r\n\t\t\t.filter((t) => t.cardId === CardIds.MechagonAdapter_BG30_MagicItem_910)\r\n\t\t\t.filter((t) => t.scriptDataNum1 > 0)[0];\r\n\t\tif (!!adapter && hasCorrectTribe(entity, hero, Race.MECH, gameState.anomalies, gameState.allCards)) {\r\n\t\t\tupdateDivineShield(entity, board, hero, otherHero, true, gameState);\r\n\t\t\tadapter.scriptDataNum1--;\r\n\t\t}\r\n\r\n\t\tfor (let i = 0; i < board.length; i++) {\r\n\t\t\tif (board[i].cardId === CardIds.BolvarFireblood_ICC_858) {\r\n\t\t\t\tmodifyStats(board[i], board[i], 2, 0, board, hero, gameState);\r\n\t\t\t\tgameState.spectator.registerPowerTarget(board[i], board[i], board, hero, otherHero);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\r\n\r\nexport const grantRandomDivineShield = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst elligibleEntities = board\r\n\t\t.filter((entity) => !entity.divineShield)\r\n\t\t.filter((entity) => entity.health > 0 && !entity.definitelyDead);\r\n\tif (elligibleEntities.length > 0) {\r\n\t\tconst chosen = pickRandom(elligibleEntities);\r\n\t\tupdateDivineShield(chosen, board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, chosen, board, null, null);\r\n\t}\r\n};\r\n\r\nexport const grantDivineShieldToLeftmostMinions = (\r\n\tsource: BoardEntity,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tquantity: number,\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tfor (let i = 0; i < Math.min(quantity, board.length); i++) {\r\n\t\tupdateDivineShield(board[i], board, hero, otherHero, true, gameState);\r\n\t\tgameState.spectator.registerPowerTarget(source, board[i], board, null, null);\r\n\t}\r\n};\r\n\r\nexport interface OnDivineShieldUpdatedInput {\r\n\tboard: BoardEntity[];\r\n\thero: BgsPlayerEntity;\r\n\totherHero: BgsPlayerEntity;\r\n\tgameState: FullGameState;\r\n\ttarget: BoardEntity;\r\n\tnewValue: boolean;\r\n\tpreviousValue: boolean;\r\n}\r\n"]}
|
package/dist/services/utils.js
CHANGED
|
@@ -38,7 +38,9 @@ function pickRandom(array, sourceEntity) {
|
|
|
38
38
|
const forced = debug_state_1.debugState.forcedRandomPicks.find((p) => debug_state_1.debugState.isCorrectEntity(p.source, sourceEntity));
|
|
39
39
|
if (forced) {
|
|
40
40
|
const match = array.find((c) => debug_state_1.debugState.isCorrectEntity(forced.target, c));
|
|
41
|
-
|
|
41
|
+
if (!forced.chosenCardId) {
|
|
42
|
+
debug_state_1.debugState.forcedRandomPicks = debug_state_1.debugState.forcedRandomPicks.filter((p) => p !== forced);
|
|
43
|
+
}
|
|
42
44
|
if (match) {
|
|
43
45
|
return match;
|
|
44
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/services/utils.ts"],"names":[],"mappings":";;;AACA,gDAA4C;AAE5C,SAAS,cAAc,CAAI,KAAmB,EAAE,aAAqB;IACpE,MAAM,WAAW,GAAQ,CAAC,GAAG,KAAK,CAAC,CAAC;IACpC,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,OAAO,WAAW,CAAC,MAAM,EAAE;QAC1B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;KAClD;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAkBQ,wCAAc;AAhBvB,KAAK,UAAU,KAAK,CAAC,EAAE;IACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC1D,CAAC;AAcwB,sBAAK;AAZvB,MAAM,eAAe,GAC3B,CAAI,YAAyC,EAAE,EAAE,CACjD,CAAC,KAAmB,EAAmC,EAAE;IACxD,OAAO,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAE,GAAG,EAAE,EAAE;;QACtD,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAChC,iBAAiB,CAAC,KAAK,CAAC,GAAG,MAAA,iBAAiB,CAAC,KAAK,CAAC,mCAAI,EAAE,CAAC;QAE1D,iBAAiB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,iBAAiB,CAAC;IAC1B,CAAC,EAAE,EAAE,CAAC,CAAC;AACR,CAAC,CAAC;AAVU,QAAA,eAAe,mBAUzB;AAMH,SAAgB,UAAU,CAAI,KAAmB,EAAE,YAA0B;IAC5E,IAAI,CAAC,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,CAAA,EAAE;QACnB,OAAO,IAAI,CAAC;KACZ;IACD,IACC,YAAY;QACZ,wBAAU,CAAC,MAAM;QACjB,KAAK,CAAC,MAAM,GAAG,CAAC;QAChB,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ;QAC5B,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI;QAChB,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,EACrB;QACD,MAAM,MAAM,GAAG,wBAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAU,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;QAC5G,IAAI,MAAM,EAAE;YACX,MAAM,KAAK,GAAI,KAAkC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAU,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;YAE5G,wBAAU,CAAC,iBAAiB,GAAG,wBAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;YACxF,IAAI,KAAK,EAAE;gBACV,OAAO,KAAU,CAAC;aAClB;SACD;KACD;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,CAAC;AAvBD,gCAuBC;AAEM,MAAM,kBAAkB,GAAG,CAAI,KAAmB,EAAE,QAAgB,EAAO,EAAE;IACnF,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE;QAClC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC,YAAY,EAAE;YACnB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SAC1B;KACD;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAVW,QAAA,kBAAkB,sBAU7B;AAEK,MAAM,eAAe,GAAG,CAAC,KAAoB,EAAe,EAAE;IACpE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAC7C,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AAJW,QAAA,eAAe,mBAI1B;AAEK,MAAM,uBAAuB,GAAG,CAAC,KAAoB,EAAE,QAAgB,EAAiB,EAAE;IAChG,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE;QAClC,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9G,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,YAAY,EAAE;YACnB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SAC1B;KACD;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAVW,QAAA,uBAAuB,2BAUlC;AAEK,MAAM,sBAAsB,GAAG,CAAC,KAAoB,EAAe,EAAE;IAC3E,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,MAAM,wBAAwB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC;IACtF,MAAM,YAAY,GAAG,UAAU,CAAC,wBAAwB,CAAC,CAAC;IAC1D,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AANW,QAAA,sBAAsB,0BAMjC;AAEK,MAAM,sBAAsB,GAAG,CAAC,KAAoB,EAAe,EAAE;IAC3E,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,MAAM,wBAAwB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC;IACtF,MAAM,YAAY,GAAG,UAAU,CAAC,wBAAwB,CAAC,CAAC;IAC1D,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AANW,QAAA,sBAAsB,0BAMjC;AAEK,MAAM,uBAAuB,GAAG,CAAC,KAAoB,EAAe,EAAE;IAC5E,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,MAAM,yBAAyB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,UAAU,CAAC,yBAAyB,CAAC,CAAC;IAC3D,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AANW,QAAA,uBAAuB,2BAMlC;AAEK,MAAM,uBAAuB,GAAG,CAAC,KAAoB,EAAe,EAAE;IAC5E,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,MAAM,yBAAyB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,UAAU,CAAC,yBAAyB,CAAC,CAAC;IAC3D,OAAO,YAAY,CAAC;AACrB,CAAC,CAAC;AANW,QAAA,uBAAuB,2BAMlC;AAEK,MAAM,MAAM,GAAG,CAAC,KAAa,EAAU,EAAE;IAE/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AALW,QAAA,MAAM,UAKjB;AAEK,MAAM,MAAM,GAAG,CAAC,MAAc,EAAU,EAAE;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,OAAO,GAAG,CAAC;AACZ,CAAC,CAAC;AAJW,QAAA,MAAM,UAIjB;AAEK,MAAM,2BAA2B,GAAG,CAAI,IAAS,EAAE,CAAS,EAAO,EAAE;IAC3E,MAAM,QAAQ,GAAG,IAAA,oBAAY,EAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACzC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC,CAAC;AAHW,QAAA,2BAA2B,+BAGtC;AAGK,MAAM,YAAY,GAAG,CAAI,KAAU,EAAO,EAAE;IAClD,IAAI,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;IAChC,IAAI,WAAW,GAAG,CAAC,CAAC;IAGpB,OAAO,YAAY,IAAI,CAAC,EAAE;QAEzB,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC;QACvD,YAAY,EAAE,CAAC;QAGf,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;KACtF;IAED,OAAO,KAAK,CAAC;AACd,CAAC,CAAC;AAfW,QAAA,YAAY,gBAevB;AAEK,MAAM,QAAQ,GAAG,CACvB,KAAmB,EACnB,SAAkE,EAC9D,EAAE;IACN,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAA,EAAE;QACrB,OAAO,IAAI,CAAC;KACZ;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAVW,QAAA,QAAQ,YAUnB","sourcesContent":["import { BoardEntity } from '../board-entity';\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>(array: readonly T[], sourceEntity: BoardEntity): T;\r\nexport function pickRandom<T>(array: readonly T[], sourceEntity?: BoardEntity): 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// Always consume when we have a matching source - each trigger gets its own pick (e.g. Titus doubles Warghoul)\r\n\t\t\tdebugState.forcedRandomPicks = debugState.forcedRandomPicks.filter((p) => p !== forced);\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 { BoardEntity } from '../board-entity';\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>(array: readonly T[], sourceEntity: BoardEntity): T;\r\nexport function pickRandom<T>(array: readonly T[], sourceEntity?: BoardEntity): 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"]}
|
|
@@ -41,7 +41,7 @@ exports.default = async (event) => {
|
|
|
41
41
|
return response;
|
|
42
42
|
};
|
|
43
43
|
const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
44
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q
|
|
44
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
45
45
|
if (!((_a = cards === null || cards === void 0 ? void 0 : cards.getCards()) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
46
46
|
console.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);
|
|
47
47
|
return null;
|
|
@@ -82,17 +82,15 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
82
82
|
attacker: { ...f.attacker },
|
|
83
83
|
defender: { ...f.defender },
|
|
84
84
|
}));
|
|
85
|
-
const rawPicks = (
|
|
86
|
-
source: { cardId: 'BG34_Giant_331' },
|
|
87
|
-
target,
|
|
88
|
-
}))) !== null && _p !== void 0 ? _p : [];
|
|
85
|
+
const rawPicks = (_m = battleInput.debugState.forcedRandomPicks) !== null && _m !== void 0 ? _m : [];
|
|
89
86
|
debug_state_1.debugState.forcedRandomPicksBase = rawPicks.map((p) => ({
|
|
90
87
|
source: { ...p.source },
|
|
91
88
|
target: { ...p.target },
|
|
89
|
+
...(p.chosenCardId && { chosenCardId: p.chosenCardId }),
|
|
92
90
|
}));
|
|
93
91
|
}
|
|
94
92
|
try {
|
|
95
|
-
!((
|
|
93
|
+
!((_o = battleInput.options) === null || _o === void 0 ? void 0 : _o.skipInfoLogs) && console.time('simulation');
|
|
96
94
|
const outcomes = {};
|
|
97
95
|
for (let i = 0; i < numberOfSimulations; i++) {
|
|
98
96
|
const input = (0, input_clone_1.cloneInput3)(inputReady);
|
|
@@ -149,7 +147,7 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
149
147
|
simulationResult.lost++;
|
|
150
148
|
simulationResult.damageLost += battleResult.damageDealt;
|
|
151
149
|
simulationResult.damageLosts.push(battleResult.damageDealt);
|
|
152
|
-
outcomes[battleResult.damageDealt] = ((
|
|
150
|
+
outcomes[battleResult.damageDealt] = ((_p = outcomes[battleResult.damageDealt]) !== null && _p !== void 0 ? _p : 0) + 1;
|
|
153
151
|
if (battleInput.playerBoard.player.hpLeft &&
|
|
154
152
|
battleResult.damageDealt >= battleInput.playerBoard.player.hpLeft) {
|
|
155
153
|
simulationResult.lostLethal++;
|
|
@@ -165,7 +163,7 @@ const simulateBattle = function* (battleInput, cards, cardsData) {
|
|
|
165
163
|
}
|
|
166
164
|
}
|
|
167
165
|
updateSimulationResult(simulationResult, inputReady, damageConfidence);
|
|
168
|
-
!((
|
|
166
|
+
!((_q = battleInput.options) === null || _q === void 0 ? void 0 : _q.skipInfoLogs) && console.timeEnd('simulation');
|
|
169
167
|
spectator.prune();
|
|
170
168
|
simulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);
|
|
171
169
|
simulationResult.damageWons = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\nimport { AllCardsService } from '@firestone-hs/reference-data';\nimport { BgsBattleInfo } from './bgs-battle-info';\nimport { hasDeathrattleSpawnEnchantment } from './cards/card.interface';\nimport { CardsData } from './cards/cards-data';\nimport { cardMappings } from './cards/impl/_card-mappings';\nimport { debugState } from './debug-state';\nimport { cloneInput3 } from './input-clone';\nimport { buildFinalInput } from './input-sanitation';\nimport { CardIds } from './services/card-ids';\nimport { SimulationResult } from './simulation-result';\nimport { FullGameState } from './simulation/internal-game-state';\nimport { SharedState } from './simulation/shared-state';\nimport { Simulator } from './simulation/simulator';\nimport { Spectator } from './simulation/spectator/spectator';\n\nlet globalCards = new AllCardsService();\n\nexport const assignCards = (cards: AllCardsService) => {\n\tglobalCards = cards;\n};\n\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\n// the more traditional callback-style handler.\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\nexport default async (event): Promise<any> => {\n\tif (!event.body?.length) {\n\t\tconsole.warn('missing event body', event);\n\t\treturn;\n\t}\n\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\n\tconst cards = globalCards;\n\tawait cards.initializeCardsDb();\n\tconst cardsData = new CardsData(cards, false);\n\tcardsData.inititialize(\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\n\t\tbattleInput.gameState?.anomalies ?? [],\n\t);\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\n\n\t// Iterate through all intermediate results to reach the final result\n\tlet result = battleIterator.next();\n\twhile (!result.done) {\n\t\tresult = battleIterator.next();\n\t}\n\n\tconst simulationResult = result.value;\n\t// console.debug('simulationResult', simulationResult);\n\n\tconst response = {\n\t\tstatusCode: 200,\n\t\tisBase64Encoded: false,\n\t\tbody: JSON.stringify(simulationResult),\n\t};\n\treturn response;\n};\n\nexport const simulateBattle = function* (\n\tbattleInput: BgsBattleInfo,\n\tcards: AllCardsService,\n\tcardsData: CardsData,\n): Generator<SimulationResult, SimulationResult, void> {\n\tif (!cards?.getCards()?.length) {\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\n\t\treturn null;\n\t}\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\n\tconst start = Date.now();\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\n\tconst hideMaxSimulationDurationWarning = battleInput.options?.hideMaxSimulationDurationWarning ?? false;\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\n\tconst damageConfidence = battleInput.options?.damageConfidence ?? 0.9;\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\n\tconst simulationResult: SimulationResult = {\n\t\twonLethal: 0,\n\t\twon: 0,\n\t\ttied: 0,\n\t\tlost: 0,\n\t\tlostLethal: 0,\n\t\tdamageWons: [],\n\t\tdamageWon: 0,\n\t\tdamageWonRange: null,\n\t\tdamageLosts: [],\n\t\tdamageLost: 0,\n\t\tdamageLostRange: null,\n\t\twonLethalPercent: undefined,\n\t\twonPercent: undefined,\n\t\ttiedPercent: undefined,\n\t\tlostPercent: undefined,\n\t\tlostLethalPercent: undefined,\n\t\taverageDamageWon: undefined,\n\t\taverageDamageLost: undefined,\n\t};\n\n\tconst spectator = new Spectator(includeOutcomeSamples);\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\n\n\t// Apply debug state from input when present (e.g. from bug report)\n\tif (battleInput.debugState) {\n\t\tdebugState.active = true;\n\t\tdebugState.forcedCurrentAttacker = battleInput.debugState.forcedCurrentAttacker;\n\t\tdebugState.forcedFaceOffBase = battleInput.debugState.forcedFaceOffBase.map((f) => ({\n\t\t\tattacker: { ...f.attacker },\n\t\t\tdefender: { ...f.defender },\n\t\t}));\n\t\tconst rawPicks =\n\t\t\tbattleInput.debugState.forcedRandomPicks ??\n\t\t\tbattleInput.debugState.forcedTimewarpedWarghoulTargets?.map((target) => ({\n\t\t\t\tsource: { cardId: 'BG34_Giant_331' },\n\t\t\t\ttarget,\n\t\t\t})) ??\n\t\t\t[];\n\t\tdebugState.forcedRandomPicksBase = rawPicks.map((p) => ({\n\t\t\tsource: { ...p.source },\n\t\t\ttarget: { ...p.target },\n\t\t}));\n\t}\n\n\ttry {\n\t\t!battleInput.options?.skipInfoLogs && console.time('simulation');\n\t\tconst outcomes = {};\n\t\tfor (let i = 0; i < numberOfSimulations; i++) {\n\t\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\n\t\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\n\t\t\tconst gameState: FullGameState = {\n\t\t\t\tallCards: cards,\n\t\t\t\tcardsData: cardsData,\n\t\t\t\tspectator: spectator,\n\t\t\t\tsharedState: new SharedState(),\n\t\t\t\tcurrentTurn: input.gameState.currentTurn,\n\t\t\t\tvalidTribes: input.gameState.validTribes,\n\t\t\t\tanomalies: input.gameState.anomalies,\n\t\t\t\tgameState: {\n\t\t\t\t\tplayer: {\n\t\t\t\t\t\tplayer: input.playerBoard.player,\n\t\t\t\t\t\tboard: input.playerBoard.board,\n\t\t\t\t\t\tteammate: input.playerTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t\topponent: {\n\t\t\t\t\t\tplayer: input.opponentBoard.player,\n\t\t\t\t\t\tboard: input.opponentBoard.board,\n\t\t\t\t\t\tteammate: input.opponentTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t\tplayerInitial: {\n\t\t\t\t\t\tplayer: inputClone.playerBoard.player,\n\t\t\t\t\t\tboard: inputClone.playerBoard.board,\n\t\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t\topponentInitial: {\n\t\t\t\t\t\tplayer: inputClone.opponentBoard.player,\n\t\t\t\t\t\tboard: inputClone.opponentBoard.board,\n\t\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t\tconst simulator = new Simulator(gameState);\n\t\t\tconst battleResult = simulator.simulateSingleBattle(gameState.gameState.player, gameState.gameState.opponent);\n\t\t\tif (Date.now() - start > maxAcceptableDuration && !hideMaxSimulationDurationWarning) {\n\t\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\n\t\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!battleResult) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (battleResult.result === 'won') {\n\t\t\t\tsimulationResult.won++;\n\t\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\n\t\t\t\tsimulationResult.damageWons.push(battleResult.damageDealt);\n\t\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\n\t\t\t\t\tsimulationResult.wonLethal++;\n\t\t\t\t}\n\t\t\t} else if (battleResult.result === 'lost') {\n\t\t\t\tsimulationResult.lost++;\n\t\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\n\t\t\t\tsimulationResult.damageLosts.push(battleResult.damageDealt);\n\t\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\n\t\t\t\tif (\n\t\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\n\t\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\n\t\t\t\t) {\n\t\t\t\t\tsimulationResult.lostLethal++;\n\t\t\t\t}\n\t\t\t} else if (battleResult.result === 'tied') {\n\t\t\t\tsimulationResult.tied++;\n\t\t\t}\n\t\t\tspectator.commitBattleResult(battleResult.result);\n\n\t\t\t// Yield intermediate result every 200 iterations\n\t\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\n\t\t\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\n\t\t\t\tyield simulationResult;\n\t\t\t}\n\t\t}\n\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\n\t\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\n\t\tspectator.prune();\n\t\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);\n\t\t// Avoid sending this verbose data\n\n\t\tsimulationResult.damageWons = [];\n\t\tsimulationResult.damageLosts = [];\n\t\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\n\t\treturn simulationResult;\n\t} finally {\n\t\tif (battleInput.debugState) {\n\t\t\tdebugState.active = false;\n\t\t}\n\t}\n};\n\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo, damageConfidence: number) => {\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\n\tsimulationResult.wonPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\n\t\tsimulationResult.won,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.wonLethalPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\n\t\tsimulationResult.wonLethal,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.lostPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\n\t\tsimulationResult.lost,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.lostLethalPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\n\t\tsimulationResult.lostLethal,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.tiedPercent = checkRounding(\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\n\t\tsimulationResult.tied,\n\t\ttotalMatches,\n\t);\n\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\n\tconst totalDamageWon = simulationResult.damageWons.reduce((a, b) => a + b, 0);\n\tconst totalDamageLost = simulationResult.damageLosts.reduce((a, b) => a + b, 0);\n\tconst damageWonRange = calculateDamageRange(simulationResult.damageWons, damageConfidence);\n\tconst damageLostRange = calculateDamageRange(simulationResult.damageLosts, damageConfidence);\n\tsimulationResult.averageDamageWon = simulationResult.won ? totalDamageWon / simulationResult.won : 0;\n\tsimulationResult.averageDamageLost = simulationResult.lost ? totalDamageLost / simulationResult.lost : 0;\n\tsimulationResult.damageWonRange = simulationResult.won ? damageWonRange : null;\n\tsimulationResult.damageLostRange = simulationResult.lost ? damageLostRange : null;\n\n\tif (\n\t\tsimulationResult.averageDamageWon > 0 &&\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\n\t) {\n\t\tconsole.warn('average damage won issue');\n\t}\n\tif (\n\t\tsimulationResult.averageDamageLost > 0 &&\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\n\t) {\n\t\tconsole.warn('average damage lost issue');\n\t}\n};\n\nconst calculateDamageRange = (damageArray: number[], damageConfidence: number): { min: number; max: number } => {\n\tif (damageArray.length === 0) {\n\t\treturn { min: 0, max: 0 };\n\t}\n\n\t// Sort the array\n\tconst sortedDamage = [...damageArray].sort((a, b) => a - b);\n\n\t// Calculate the 10th and 90th percentiles\n\tconst percentile = (arr: number[], p: number) => {\n\t\tconst index = Math.floor(p * arr.length);\n\t\treturn arr[index];\n\t};\n\n\tconst minDamage = percentile(sortedDamage, 1 - damageConfidence);\n\tconst maxDamage = percentile(sortedDamage, damageConfidence);\n\n\treturn { min: minDamage, max: maxDamage };\n};\n\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\n\tif (roundedValue === 0 && initialValue !== 0) {\n\t\treturn 0.01;\n\t}\n\tif (roundedValue === 100 && initialValue !== totalValue) {\n\t\treturn 99.9;\n\t}\n\treturn roundedValue;\n};\n\n// Used when triggering random deathrattles\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\n\tCardIds.LivingSpores_LivingSporesEnchantment,\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\n\tCardIds.Sneed_SneedsReplicator,\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\n\tCardIds.FireRecollectionEnchantment,\n\tCardIds.LightningRecollectionEnchantment,\n\tCardIds.WaterRecollectionEnchantment,\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\n\tCardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172e,\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172_Ge,\n\tCardIds.TamsinRoame_ImpendingSacrificeEnchantment_BG20_HERO_282e2,\n];\nconst validDeathrattleEnchantmentsFromMapping = [];\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\n\t\treturn true;\n\t}\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\n\t\t\t// Also includes non-enchantments, but since we only match this against the enchants list, it's fine\n\t\t\tif (hasDeathrattleSpawnEnchantment(cardImpl)) {\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\n\t\t\t}\n\t\t}\n\t}\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\n};\n\n// const cleanEnchantmentsForEntity = (\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\n// \tentityIds: readonly number[],\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\n// \treturn enchantments.filter(\n// \t\t(enchant) =>\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\n// \t);\n// };\n"]}
|
|
1
|
+
{"version":3,"file":"simulate-bgs-battle.js","sourceRoot":"","sources":["../src/simulate-bgs-battle.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\nimport { AllCardsService } from '@firestone-hs/reference-data';\nimport { BgsBattleInfo } from './bgs-battle-info';\nimport { hasDeathrattleSpawnEnchantment } from './cards/card.interface';\nimport { CardsData } from './cards/cards-data';\nimport { cardMappings } from './cards/impl/_card-mappings';\nimport { debugState } from './debug-state';\nimport { cloneInput3 } from './input-clone';\nimport { buildFinalInput } from './input-sanitation';\nimport { CardIds } from './services/card-ids';\nimport { SimulationResult } from './simulation-result';\nimport { FullGameState } from './simulation/internal-game-state';\nimport { SharedState } from './simulation/shared-state';\nimport { Simulator } from './simulation/simulator';\nimport { Spectator } from './simulation/spectator/spectator';\n\nlet globalCards = new AllCardsService();\n\nexport const assignCards = (cards: AllCardsService) => {\n\tglobalCards = cards;\n};\n\n// This example demonstrates a NodeJS 8.10 async handler[1], however of course you could use\n// the more traditional callback-style handler.\n// [1]: https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/\nexport default async (event): Promise<any> => {\n\tif (!event.body?.length) {\n\t\tconsole.warn('missing event body', event);\n\t\treturn;\n\t}\n\n\tconst battleInput: BgsBattleInfo = JSON.parse(event.body);\n\tconst cards = globalCards;\n\tawait cards.initializeCardsDb();\n\tconst cardsData = new CardsData(cards, false);\n\tcardsData.inititialize(\n\t\tbattleInput.gameState?.validTribes ?? battleInput.options?.validTribes,\n\t\tbattleInput.gameState?.anomalies ?? [],\n\t);\n\tconst battleIterator = simulateBattle(battleInput, cards, cardsData);\n\n\t// Iterate through all intermediate results to reach the final result\n\tlet result = battleIterator.next();\n\twhile (!result.done) {\n\t\tresult = battleIterator.next();\n\t}\n\n\tconst simulationResult = result.value;\n\t// console.debug('simulationResult', simulationResult);\n\n\tconst response = {\n\t\tstatusCode: 200,\n\t\tisBase64Encoded: false,\n\t\tbody: JSON.stringify(simulationResult),\n\t};\n\treturn response;\n};\n\nexport const simulateBattle = function* (\n\tbattleInput: BgsBattleInfo,\n\tcards: AllCardsService,\n\tcardsData: CardsData,\n): Generator<SimulationResult, SimulationResult, void> {\n\tif (!cards?.getCards()?.length) {\n\t\tconsole.error('[simulate-bgs-battle] reference cards are empty, cannot simulate battle', cards);\n\t\treturn null;\n\t}\n\t// !battleInput.options?.skipInfoLogs && console.time('full-sim');\n\tconst start = Date.now();\n\tconst maxAcceptableDuration = battleInput.options?.maxAcceptableDuration || 8000;\n\tconst hideMaxSimulationDurationWarning = battleInput.options?.hideMaxSimulationDurationWarning ?? false;\n\tconst numberOfSimulations = battleInput.options?.numberOfSimulations || 8000;\n\tconst intermediateSteps = battleInput.options?.intermediateResults ?? 200;\n\tconst damageConfidence = battleInput.options?.damageConfidence ?? 0.9;\n\tconst includeOutcomeSamples = battleInput.options?.includeOutcomeSamples ?? true;\n\tconst simulationResult: SimulationResult = {\n\t\twonLethal: 0,\n\t\twon: 0,\n\t\ttied: 0,\n\t\tlost: 0,\n\t\tlostLethal: 0,\n\t\tdamageWons: [],\n\t\tdamageWon: 0,\n\t\tdamageWonRange: null,\n\t\tdamageLosts: [],\n\t\tdamageLost: 0,\n\t\tdamageLostRange: null,\n\t\twonLethalPercent: undefined,\n\t\twonPercent: undefined,\n\t\ttiedPercent: undefined,\n\t\tlostPercent: undefined,\n\t\tlostLethalPercent: undefined,\n\t\taverageDamageWon: undefined,\n\t\taverageDamageLost: undefined,\n\t};\n\n\tconst spectator = new Spectator(includeOutcomeSamples);\n\tconst inputReady = buildFinalInput(battleInput, cards, cardsData);\n\n\t// Apply debug state from input when present (e.g. from bug report)\n\tif (battleInput.debugState) {\n\t\tdebugState.active = true;\n\t\tdebugState.forcedCurrentAttacker = battleInput.debugState.forcedCurrentAttacker;\n\t\tdebugState.forcedFaceOffBase = battleInput.debugState.forcedFaceOffBase.map((f) => ({\n\t\t\tattacker: { ...f.attacker },\n\t\t\tdefender: { ...f.defender },\n\t\t}));\n\t\tconst rawPicks = battleInput.debugState.forcedRandomPicks ?? [];\n\t\tdebugState.forcedRandomPicksBase = rawPicks.map((p) => ({\n\t\t\tsource: { ...p.source },\n\t\t\ttarget: { ...p.target },\n\t\t\t...(p.chosenCardId && { chosenCardId: p.chosenCardId }),\n\t\t}));\n\t}\n\n\ttry {\n\t\t!battleInput.options?.skipInfoLogs && console.time('simulation');\n\t\tconst outcomes = {};\n\t\tfor (let i = 0; i < numberOfSimulations; i++) {\n\t\t\tconst input: BgsBattleInfo = cloneInput3(inputReady);\n\t\t\tconst inputClone: BgsBattleInfo = cloneInput3(inputReady);\n\t\t\tconst gameState: FullGameState = {\n\t\t\t\tallCards: cards,\n\t\t\t\tcardsData: cardsData,\n\t\t\t\tspectator: spectator,\n\t\t\t\tsharedState: new SharedState(),\n\t\t\t\tcurrentTurn: input.gameState.currentTurn,\n\t\t\t\tvalidTribes: input.gameState.validTribes,\n\t\t\t\tanomalies: input.gameState.anomalies,\n\t\t\t\tgameState: {\n\t\t\t\t\tplayer: {\n\t\t\t\t\t\tplayer: input.playerBoard.player,\n\t\t\t\t\t\tboard: input.playerBoard.board,\n\t\t\t\t\t\tteammate: input.playerTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t\topponent: {\n\t\t\t\t\t\tplayer: input.opponentBoard.player,\n\t\t\t\t\t\tboard: input.opponentBoard.board,\n\t\t\t\t\t\tteammate: input.opponentTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t\tplayerInitial: {\n\t\t\t\t\t\tplayer: inputClone.playerBoard.player,\n\t\t\t\t\t\tboard: inputClone.playerBoard.board,\n\t\t\t\t\t\tteammate: inputClone.playerTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t\topponentInitial: {\n\t\t\t\t\t\tplayer: inputClone.opponentBoard.player,\n\t\t\t\t\t\tboard: inputClone.opponentBoard.board,\n\t\t\t\t\t\tteammate: inputClone.opponentTeammateBoard,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t\tconst simulator = new Simulator(gameState);\n\t\t\tconst battleResult = simulator.simulateSingleBattle(\n\t\t\t\tgameState.gameState.player,\n\t\t\t\tgameState.gameState.opponent,\n\t\t\t);\n\t\t\tif (Date.now() - start > maxAcceptableDuration && !hideMaxSimulationDurationWarning) {\n\t\t\t\t// Can happen in case of inifinite boards, or a bug. Don't hog the user's computer in that case\n\t\t\t\tconsole.warn('Stopping simulation after', i, 'iterations and ', Date.now() - start, 'ms');\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!battleResult) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (battleResult.result === 'won') {\n\t\t\t\tsimulationResult.won++;\n\t\t\t\tsimulationResult.damageWon += battleResult.damageDealt;\n\t\t\t\tsimulationResult.damageWons.push(battleResult.damageDealt);\n\t\t\t\tif (battleResult.damageDealt >= battleInput.opponentBoard.player.hpLeft) {\n\t\t\t\t\tsimulationResult.wonLethal++;\n\t\t\t\t}\n\t\t\t} else if (battleResult.result === 'lost') {\n\t\t\t\tsimulationResult.lost++;\n\t\t\t\tsimulationResult.damageLost += battleResult.damageDealt;\n\t\t\t\tsimulationResult.damageLosts.push(battleResult.damageDealt);\n\t\t\t\toutcomes[battleResult.damageDealt] = (outcomes[battleResult.damageDealt] ?? 0) + 1;\n\t\t\t\tif (\n\t\t\t\t\tbattleInput.playerBoard.player.hpLeft &&\n\t\t\t\t\tbattleResult.damageDealt >= battleInput.playerBoard.player.hpLeft\n\t\t\t\t) {\n\t\t\t\t\tsimulationResult.lostLethal++;\n\t\t\t\t}\n\t\t\t} else if (battleResult.result === 'tied') {\n\t\t\t\tsimulationResult.tied++;\n\t\t\t}\n\t\t\tspectator.commitBattleResult(battleResult.result);\n\n\t\t\t// Yield intermediate result every 200 iterations\n\t\t\tif (!!intermediateSteps && i > 0 && i % intermediateSteps === 0) {\n\t\t\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\n\t\t\t\tyield simulationResult;\n\t\t\t}\n\t\t}\n\t\tupdateSimulationResult(simulationResult, inputReady, damageConfidence);\n\t\t!battleInput.options?.skipInfoLogs && console.timeEnd('simulation');\n\t\tspectator.prune();\n\t\tsimulationResult.outcomeSamples = spectator.buildOutcomeSamples(battleInput.gameState);\n\t\t// Avoid sending this verbose data\n\n\t\tsimulationResult.damageWons = [];\n\t\tsimulationResult.damageLosts = [];\n\t\t// !battleInput.options?.skipInfoLogs && console.timeEnd('full-sim');\n\t\treturn simulationResult;\n\t} finally {\n\t\tif (battleInput.debugState) {\n\t\t\tdebugState.active = false;\n\t\t}\n\t}\n};\n\nconst updateSimulationResult = (simulationResult: SimulationResult, input: BgsBattleInfo, damageConfidence: number) => {\n\tconst totalMatches = simulationResult.won + simulationResult.tied + simulationResult.lost;\n\tsimulationResult.wonPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.won)) / totalMatches) / 10,\n\t\tsimulationResult.won,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.wonLethalPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10,\n\t\tsimulationResult.wonLethal,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.lostPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.lost)) / totalMatches) / 10,\n\t\tsimulationResult.lost,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.lostLethalPercent = checkRounding(\n\t\tMath.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10,\n\t\tsimulationResult.lostLethal,\n\t\ttotalMatches,\n\t);\n\tsimulationResult.tiedPercent = checkRounding(\n\t\tMath.max(0, 100 - simulationResult.lostPercent - simulationResult.wonPercent),\n\t\tsimulationResult.tied,\n\t\ttotalMatches,\n\t);\n\n\t// simulationResult.wonLethalPercent = Math.round((10 * (100 * simulationResult.wonLethal)) / totalMatches) / 10;\n\t// simulationResult.lostLethalPercent = Math.round((10 * (100 * simulationResult.lostLethal)) / totalMatches) / 10;\n\tconst totalDamageWon = simulationResult.damageWons.reduce((a, b) => a + b, 0);\n\tconst totalDamageLost = simulationResult.damageLosts.reduce((a, b) => a + b, 0);\n\tconst damageWonRange = calculateDamageRange(simulationResult.damageWons, damageConfidence);\n\tconst damageLostRange = calculateDamageRange(simulationResult.damageLosts, damageConfidence);\n\tsimulationResult.averageDamageWon = simulationResult.won ? totalDamageWon / simulationResult.won : 0;\n\tsimulationResult.averageDamageLost = simulationResult.lost ? totalDamageLost / simulationResult.lost : 0;\n\tsimulationResult.damageWonRange = simulationResult.won ? damageWonRange : null;\n\tsimulationResult.damageLostRange = simulationResult.lost ? damageLostRange : null;\n\n\tif (\n\t\tsimulationResult.averageDamageWon > 0 &&\n\t\tsimulationResult.averageDamageWon < input.playerBoard.player.tavernTier\n\t) {\n\t\tconsole.warn('average damage won issue');\n\t}\n\tif (\n\t\tsimulationResult.averageDamageLost > 0 &&\n\t\tsimulationResult.averageDamageLost < input.opponentBoard.player.tavernTier\n\t) {\n\t\tconsole.warn('average damage lost issue');\n\t}\n};\n\nconst calculateDamageRange = (damageArray: number[], damageConfidence: number): { min: number; max: number } => {\n\tif (damageArray.length === 0) {\n\t\treturn { min: 0, max: 0 };\n\t}\n\n\t// Sort the array\n\tconst sortedDamage = [...damageArray].sort((a, b) => a - b);\n\n\t// Calculate the 10th and 90th percentiles\n\tconst percentile = (arr: number[], p: number) => {\n\t\tconst index = Math.floor(p * arr.length);\n\t\treturn arr[index];\n\t};\n\n\tconst minDamage = percentile(sortedDamage, 1 - damageConfidence);\n\tconst maxDamage = percentile(sortedDamage, damageConfidence);\n\n\treturn { min: minDamage, max: maxDamage };\n};\n\nconst checkRounding = (roundedValue: number, initialValue: number, totalValue: number): number => {\n\tif (roundedValue === 0 && initialValue !== 0) {\n\t\treturn 0.01;\n\t}\n\tif (roundedValue === 100 && initialValue !== totalValue) {\n\t\treturn 99.9;\n\t}\n\treturn roundedValue;\n};\n\n// Used when triggering random deathrattles\nconst VALID_DEATHRATTLE_ENCHANTMENTS = [\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_BG_BOT_312e,\n\tCardIds.ReplicatingMenace_ReplicatingMenaceEnchantment_TB_BaconUps_032e,\n\tCardIds.LivingSpores_LivingSporesEnchantment,\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000e,\n\tCardIds.Leapfrogger_LeapfrogginEnchantment_BG21_000_Ge,\n\tCardIds.Sneed_SneedsReplicator,\n\tCardIds.SneedsReplicator_ReplicateEnchantment,\n\tCardIds.EarthRecollectionEnchantment, // Spirit Raptor\n\tCardIds.FireRecollectionEnchantment,\n\tCardIds.LightningRecollectionEnchantment,\n\tCardIds.WaterRecollectionEnchantment,\n\tCardIds.EarthInvocation_ElementEarthEnchantment, // Summon a 1/1\n\tCardIds.LightningInvocation, // Deal 1 damage to 5 enemy minions\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004e,\n\t// CardIds.SurfNSurf_CrabRidingEnchantment_BG27_004_Ge,\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055e,\n\t// CardIds.RecurringNightmare_NightmareInsideEnchantment_BG26_055_Ge,\n\tCardIds.BoonOfBeetles_BeetleSwarmEnchantment_BG28_603e,\n\tCardIds.RustyTrident_TridentsTreasureEnchantment_BG30_MagicItem_917e,\n\tCardIds.HoggyBank_GemInTheBankEnchantment_BG30_MagicItem_411e,\n\tCardIds.JarredFrostling_FrostyGlobeEnchantment_BG30_MagicItem_952e,\n\tCardIds.CaduceusReactor_CaduceusReactorEnchantment_BG31_HERO_801ptee,\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172e,\n\tCardIds.AutoAssembler_AutoAssemblerEnchantment_BG32_172_Ge,\n\tCardIds.TamsinRoame_ImpendingSacrificeEnchantment_BG20_HERO_282e2,\n];\nconst validDeathrattleEnchantmentsFromMapping = [];\nexport const isValidDeathrattleEnchantment = (cardId: string): boolean => {\n\tif (VALID_DEATHRATTLE_ENCHANTMENTS.includes(cardId as CardIds)) {\n\t\treturn true;\n\t}\n\tif (validDeathrattleEnchantmentsFromMapping.length === 0) {\n\t\tfor (const cardImpl of Object.values(cardMappings)) {\n\t\t\t// Also includes non-enchantments, but since we only match this against the enchants list, it's fine\n\t\t\tif (hasDeathrattleSpawnEnchantment(cardImpl)) {\n\t\t\t\tvalidDeathrattleEnchantmentsFromMapping.push(...cardImpl.cardIds);\n\t\t\t}\n\t\t}\n\t}\n\treturn validDeathrattleEnchantmentsFromMapping.includes(cardId);\n};\n\n// const cleanEnchantmentsForEntity = (\n// \tenchantments: { cardId: string; originEntityId?: number; timing: number }[],\n// \tentityIds: readonly number[],\n// ): { cardId: string; originEntityId?: number; timing: number }[] => {\n// \treturn enchantments.filter(\n// \t\t(enchant) =>\n// \t\t\tentityIds.indexOf(enchant.originEntityId) !== -1 ||\n// \t\t\tvalidEnchantments.indexOf(enchant.cardId as CardIds) !== -1,\n// \t);\n// };\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { BgsPlayerEntity } from '../bgs-player-entity';
|
|
2
2
|
import { BoardEntity } from '../board-entity';
|
|
3
3
|
import { FullGameState } from './internal-game-state';
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const addMinionToBoard: (board: BoardEntity[], boardHero: BgsPlayerEntity, otherBoard: BoardEntity[], otherHero: BgsPlayerEntity, index: number, minionToAdd: BoardEntity, gameState: FullGameState, performAfterSpawnEffects?: boolean, applySelfAuras?: boolean) => void;
|
|
4
|
+
export declare const addMinionToBoard: (board: BoardEntity[], boardHero: BgsPlayerEntity, otherBoard: BoardEntity[], otherHero: BgsPlayerEntity, index: number, minionToAdd: BoardEntity, gameState: FullGameState, applySelfAuras?: boolean) => void;
|
|
6
5
|
export declare const handleAddedMinionAuraEffect: (board: BoardEntity[], boardHero: BgsPlayerEntity, otherBoard: BoardEntity[], otherHero: BgsPlayerEntity, spawned: BoardEntity, gameState: FullGameState, applySelfAuras?: boolean, isActuallySpawned?: boolean) => void;
|
|
7
6
|
export declare const applyAurasToSelf: (spawned: BoardEntity, board: BoardEntity[], boardHero: BgsPlayerEntity, gameState: FullGameState) => void;
|
|
8
7
|
export declare const removeAurasFromSelf: (entity: BoardEntity, board: BoardEntity[], boardHero: BgsPlayerEntity, gameState: FullGameState) => void;
|
|
8
|
+
export declare const handleAfterSpawnEffects: (board: BoardEntity[], hero: BgsPlayerEntity, otherBoard: BoardEntity[], otherHero: BgsPlayerEntity, allSpawned: readonly BoardEntity[], gameState: FullGameState) => void;
|
|
9
9
|
export declare const onMinionSummoned: (hero: BgsPlayerEntity, board: BoardEntity[], gameState: FullGameState) => void;
|
|
10
10
|
export interface OnSpawnInput {
|
|
11
11
|
hero: BgsPlayerEntity;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.onMinionSummoned = exports.
|
|
3
|
+
exports.onMinionSummoned = exports.handleAfterSpawnEffects = exports.removeAurasFromSelf = exports.applyAurasToSelf = exports.handleAddedMinionAuraEffect = exports.addMinionToBoard = void 0;
|
|
4
4
|
const reference_data_1 = require("@firestone-hs/reference-data");
|
|
5
5
|
const card_interface_1 = require("../cards/card.interface");
|
|
6
6
|
const cards_data_1 = require("../cards/cards-data");
|
|
@@ -12,21 +12,11 @@ const utils_1 = require("../services/utils");
|
|
|
12
12
|
const utils_2 = require("../utils");
|
|
13
13
|
const quest_1 = require("./quest");
|
|
14
14
|
const stats_1 = require("./stats");
|
|
15
|
-
const
|
|
16
|
-
for (const minionToAdd of [...minionsToAdd].reverse()) {
|
|
17
|
-
(0, exports.addMinionToBoard)(board, boardHero, otherBoard, otherHero, index, minionToAdd, gameState, false);
|
|
18
|
-
}
|
|
19
|
-
handleAfterSpawnEffects(board, boardHero, otherBoard, otherHero, minionsToAdd, gameState);
|
|
20
|
-
};
|
|
21
|
-
exports.addMinionsToBoard = addMinionsToBoard;
|
|
22
|
-
const addMinionToBoard = (board, boardHero, otherBoard, otherHero, index, minionToAdd, gameState, performAfterSpawnEffects = true, applySelfAuras = true) => {
|
|
15
|
+
const addMinionToBoard = (board, boardHero, otherBoard, otherHero, index, minionToAdd, gameState, applySelfAuras = true) => {
|
|
23
16
|
board.splice(index, 0, minionToAdd);
|
|
24
17
|
(0, exports.handleAddedMinionAuraEffect)(board, boardHero, otherBoard, otherHero, minionToAdd, gameState, applySelfAuras);
|
|
25
18
|
(0, exports.onMinionSummoned)(boardHero, board, gameState);
|
|
26
19
|
handleSpawnEffect(board, boardHero, otherBoard, otherHero, minionToAdd, gameState, applySelfAuras);
|
|
27
|
-
if (performAfterSpawnEffects) {
|
|
28
|
-
handleAfterSpawnEffects(board, boardHero, otherBoard, otherHero, [minionToAdd], gameState);
|
|
29
|
-
}
|
|
30
20
|
};
|
|
31
21
|
exports.addMinionToBoard = addMinionToBoard;
|
|
32
22
|
const handleSpawnEffect = (board, boardHero, otherBoard, otherHero, spawned, gameState, applySelfAuras = true) => {
|
|
@@ -537,6 +527,7 @@ const handleAfterSpawnEffects = (board, hero, otherBoard, otherHero, allSpawned,
|
|
|
537
527
|
handleAfterSpawnEffect(board, hero, otherBoard, otherHero, spawned, gameState);
|
|
538
528
|
}
|
|
539
529
|
};
|
|
530
|
+
exports.handleAfterSpawnEffects = handleAfterSpawnEffects;
|
|
540
531
|
const onMinionSummoned = (hero, board, gameState) => {
|
|
541
532
|
var _a;
|
|
542
533
|
const quests = (_a = hero.questEntities) !== null && _a !== void 0 ? _a : [];
|