@firestone-hs/simulate-bgs-battle 1.1.739 → 1.1.740
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/board-entity.d.ts +1 -0
- package/dist/board-entity.js.map +1 -1
- package/dist/cards/impl/minion/sinrunner-blanchy.js +10 -7
- package/dist/cards/impl/minion/sinrunner-blanchy.js.map +1 -1
- package/dist/input-sanitation.js +1 -0
- package/dist/input-sanitation.js.map +1 -1
- package/package.json +1 -1
package/dist/board-entity.d.ts
CHANGED
package/dist/board-entity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-entity.js","sourceRoot":"","sources":["../src/board-entity.ts"],"names":[],"mappings":"","sourcesContent":["export interface BoardEntity {\r\n\tentityId: number;\r\n\tcardId: string;\r\n\tattack: number;\r\n\thealth: number;\r\n\r\n\tmaxHealth?: number;\r\n\tmaxAttack?: number;\r\n\tavengeCurrent?: number;\r\n\tavengeDefault?: number;\r\n\tfrenzyChargesLeft?: number;\r\n\tdefinitelyDead?: boolean;\r\n\ttaunt?: boolean;\r\n\tdivineShield?: boolean;\r\n\tstrongDivineShield?: boolean;\r\n\t// Number of times the Divine Shield survives being popped, on top of `strongDivineShield`\r\n\textraDivineShieldCharges?: number;\r\n\tpoisonous?: boolean;\r\n\tvenomous?: boolean;\r\n\treborn?: boolean;\r\n\trebornFromEntityId?: number;\r\n\tcleave?: boolean;\r\n\twindfury?: boolean;\r\n\tstealth?: boolean;\r\n\tenchantments?: BoardEnchantment[];\r\n\tpendingAttackBuffs?: number[];\r\n\tscriptDataNum1?: number;\r\n\tscriptDataNum2?: number;\r\n\tscriptDataNum3?: number;\r\n\tscriptDataNum4?: number;\r\n\tscriptDataNum5?: number;\r\n\tscriptDataNum6?: number;\r\n\tinInitialState?: boolean;\r\n\t// For Build-An-Undead and Zilliax\r\n\tadditionalCards?: readonly string[] | null;\r\n\tdynamicInfo?: readonly any[] | null;\r\n\ttags?: { [tag: number]: number };\r\n\r\n\t// When using this as a remembered deathrattle\r\n\toriginalCardId?: string;\r\n\r\n\t// We only store the card id, because we want all the attack and other data to be computed at runtime, based on the\r\n\t// current stats of the Fish\r\n\trememberedDeathrattles?: BoardEnchantment[];\r\n\tdeathrattleRepeats?: number;\r\n\tdamageMultiplier?: number;\r\n\tlocked?: boolean;\r\n\tfriendly?: boolean;\r\n\tcantAttack?: boolean;\r\n\thasAttacked?: number;\r\n\timmuneWhenAttackCharges?: number;\r\n\tattackImmediately?: boolean;\r\n\t// Used only to handle murkeye aura?\r\n\tpreviousAttack?: number;\r\n\tlastAffectedByEntity?: BoardEntity;\r\n\t// attacking?: boolean;\r\n\t// Did it have divine shield at least once? (for Sinrunner Blanchy)\r\n\thadDivineShield?: boolean;\r\n\tabiityChargesLeft?: number;\r\n\tindexFromLeftAtTimeOfDeath?: number;\r\n\tspawnIndexFromRight?: number;\r\n\r\n\t// permanentAttack?: number;\r\n\t// permanentHealth?: number;\r\n\ttavernTier?: number;\r\n\r\n\tmemory?: any;\r\n\tgildedInCombat?: boolean;\r\n\r\n\tonCanceledSummon?: () => void;\r\n\tonResolve?: (() => void)[];\r\n}\r\n\r\nexport interface BoardEnchantment {\r\n\tcardId: string;\r\n\toriginEntityId?: number;\r\n\ttagScriptDataNum1?: number;\r\n\ttagScriptDataNum2?: number;\r\n\ttiming: number;\r\n\trepeats?: number;\r\n\tvalue?: number;\r\n\tmemory?: any;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"board-entity.js","sourceRoot":"","sources":["../src/board-entity.ts"],"names":[],"mappings":"","sourcesContent":["export interface BoardEntity {\r\n\tentityId: number;\r\n\tcardId: string;\r\n\tattack: number;\r\n\thealth: number;\r\n\r\n\tmaxHealth?: number;\r\n\tmaxAttack?: number;\r\n\tavengeCurrent?: number;\r\n\tavengeDefault?: number;\r\n\tfrenzyChargesLeft?: number;\r\n\tdefinitelyDead?: boolean;\r\n\ttaunt?: boolean;\r\n\tdivineShield?: boolean;\r\n\tstrongDivineShield?: boolean;\r\n\t// Number of times the Divine Shield survives being popped, on top of `strongDivineShield`\r\n\textraDivineShieldCharges?: number;\r\n\tpoisonous?: boolean;\r\n\t// Used for Persisting Horror\r\n\thadVenomous?: boolean;\r\n\tvenomous?: boolean;\r\n\treborn?: boolean;\r\n\trebornFromEntityId?: number;\r\n\tcleave?: boolean;\r\n\twindfury?: boolean;\r\n\tstealth?: boolean;\r\n\tenchantments?: BoardEnchantment[];\r\n\tpendingAttackBuffs?: number[];\r\n\tscriptDataNum1?: number;\r\n\tscriptDataNum2?: number;\r\n\tscriptDataNum3?: number;\r\n\tscriptDataNum4?: number;\r\n\tscriptDataNum5?: number;\r\n\tscriptDataNum6?: number;\r\n\tinInitialState?: boolean;\r\n\t// For Build-An-Undead and Zilliax\r\n\tadditionalCards?: readonly string[] | null;\r\n\tdynamicInfo?: readonly any[] | null;\r\n\ttags?: { [tag: number]: number };\r\n\r\n\t// When using this as a remembered deathrattle\r\n\toriginalCardId?: string;\r\n\r\n\t// We only store the card id, because we want all the attack and other data to be computed at runtime, based on the\r\n\t// current stats of the Fish\r\n\trememberedDeathrattles?: BoardEnchantment[];\r\n\tdeathrattleRepeats?: number;\r\n\tdamageMultiplier?: number;\r\n\tlocked?: boolean;\r\n\tfriendly?: boolean;\r\n\tcantAttack?: boolean;\r\n\thasAttacked?: number;\r\n\timmuneWhenAttackCharges?: number;\r\n\tattackImmediately?: boolean;\r\n\t// Used only to handle murkeye aura?\r\n\tpreviousAttack?: number;\r\n\tlastAffectedByEntity?: BoardEntity;\r\n\t// attacking?: boolean;\r\n\t// Did it have divine shield at least once? (for Sinrunner Blanchy)\r\n\thadDivineShield?: boolean;\r\n\tabiityChargesLeft?: number;\r\n\tindexFromLeftAtTimeOfDeath?: number;\r\n\tspawnIndexFromRight?: number;\r\n\r\n\t// permanentAttack?: number;\r\n\t// permanentHealth?: number;\r\n\ttavernTier?: number;\r\n\r\n\tmemory?: any;\r\n\tgildedInCombat?: boolean;\r\n\r\n\tonCanceledSummon?: () => void;\r\n\tonResolve?: (() => void)[];\r\n}\r\n\r\nexport interface BoardEnchantment {\r\n\tcardId: string;\r\n\toriginEntityId?: number;\r\n\ttagScriptDataNum1?: number;\r\n\ttagScriptDataNum2?: number;\r\n\ttiming: number;\r\n\trepeats?: number;\r\n\tvalue?: number;\r\n\tmemory?: any;\r\n}\r\n"]}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isSinrunnerBlanchy = exports.buildSinrunnerBlanchyRebornEntity = void 0;
|
|
4
|
-
const buildSinrunnerBlanchyRebornEntity = (deadEntity) =>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
const buildSinrunnerBlanchyRebornEntity = (deadEntity) => {
|
|
5
|
+
return {
|
|
6
|
+
...deadEntity,
|
|
7
|
+
hasAttacked: undefined,
|
|
8
|
+
health: deadEntity.maxHealth,
|
|
9
|
+
divineShield: deadEntity.hadDivineShield,
|
|
10
|
+
reborn: false,
|
|
11
|
+
venomous: deadEntity.venomous || deadEntity.hadVenomous,
|
|
12
|
+
};
|
|
13
|
+
};
|
|
11
14
|
exports.buildSinrunnerBlanchyRebornEntity = buildSinrunnerBlanchyRebornEntity;
|
|
12
15
|
const isSinrunnerBlanchy = (cardId) => cardId === "BG24_005" || cardId === "BG24_005_G";
|
|
13
16
|
exports.isSinrunnerBlanchy = isSinrunnerBlanchy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sinrunner-blanchy.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/sinrunner-blanchy.ts"],"names":[],"mappings":";;;AAIO,MAAM,iCAAiC,GAAG,CAAC,UAAuB,EAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"sinrunner-blanchy.js","sourceRoot":"","sources":["../../../../src/cards/impl/minion/sinrunner-blanchy.ts"],"names":[],"mappings":";;;AAIO,MAAM,iCAAiC,GAAG,CAAC,UAAuB,EAAe,EAAE;IACzF,OAAO;QACN,GAAG,UAAU;QACb,WAAW,EAAE,SAAS;QACtB,MAAM,EAAE,UAAU,CAAC,SAAS;QAC5B,YAAY,EAAE,UAAU,CAAC,eAAe;QACxC,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,UAAU,CAAC,QAAQ,IAAI,UAAU,CAAC,WAAW;KACvD,CAAC;AACH,CAAC,CAAC;AATW,QAAA,iCAAiC,qCAS5C;AAEK,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAW,EAAE,CAC7D,MAAM,eAAsC,IAAI,MAAM,iBAAwC,CAAC;AADnF,QAAA,kBAAkB,sBACiE","sourcesContent":["import { BoardEntity } from '../../../board-entity';\r\nimport { CardIds } from '../../../services/card-ids';\r\n\r\n/** Reborn with full stats and bonus keywords (enchantments stripped by spread + fresh entity). */\r\nexport const buildSinrunnerBlanchyRebornEntity = (deadEntity: BoardEntity): BoardEntity => {\r\n\treturn {\r\n\t\t...deadEntity,\r\n\t\thasAttacked: undefined,\r\n\t\thealth: deadEntity.maxHealth,\r\n\t\tdivineShield: deadEntity.hadDivineShield,\r\n\t\treborn: false,\r\n\t\tvenomous: deadEntity.venomous || deadEntity.hadVenomous,\r\n\t};\r\n};\r\n\r\nexport const isSinrunnerBlanchy = (cardId: string): boolean =>\r\n\tcardId === CardIds.SinrunnerBlanchy_BG24_005 || cardId === CardIds.SinrunnerBlanchy_BG24_005_G;\r\n"]}
|
package/dist/input-sanitation.js
CHANGED
|
@@ -97,6 +97,7 @@ const sanitizeEntity = (entity, isPlayer, cardsData, cards, applyDefaultScriptDa
|
|
|
97
97
|
}
|
|
98
98
|
(0, utils_1.addImpliedMechanics)(fixed, cardsData);
|
|
99
99
|
fixed.friendly = isPlayer;
|
|
100
|
+
fixed.hadVenomous = fixed.venomous;
|
|
100
101
|
return fixed;
|
|
101
102
|
};
|
|
102
103
|
const buildFinalInputBoard = (playerInfo, isPlayer, cardsData, cards) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-sanitation.js","sourceRoot":"","sources":["../src/input-sanitation.ts"],"names":[],"mappings":"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","sourcesContent":["import { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BgsBoardInfo } from './bgs-board-info';\r\nimport { BgsHeroPower, BgsPlayerEntity } from './bgs-player-entity';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { CardIds } from './services/card-ids';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { fixEnchantments } from './simulation/enchantments';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nexport const buildFinalInput = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): BgsBattleInfo => {\r\n\tconst entityIdContainer = { entityId: 999_999_999 };\r\n\r\n\tconst {\r\n\t\tboard: playerBoard,\r\n\t\thand: playerHand,\r\n\t\tplayer: playerEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: playerTeammateBoard,\r\n\t\thand: playerTeammateHand,\r\n\t\tplayer: playerTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerTeammateBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\tconst {\r\n\t\tboard: opponentBoard,\r\n\t\thand: opponentHand,\r\n\t\tplayer: opponentEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: opponentTeammateBoard,\r\n\t\thand: opponentTeammateHand,\r\n\t\tplayer: opponentTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentTeammateBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerEntity,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tplayerTeammateBoard: !!playerTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: playerTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...playerTeammateEntity,\r\n\t\t\t\t\t\thand: playerTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentEntity,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentTeammateBoard: !!opponentTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: opponentTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...opponentTeammateEntity,\r\n\t\t\t\t\t\thand: opponentTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\tgameState: {\r\n\t\t\t...battleInput.gameState,\r\n\t\t\tanomalies: battleInput.gameState.anomalies?.filter((a) => !!a) ?? ([] as readonly string[]),\r\n\t\t},\r\n\t\t// Combat-affecting options (e.g. applyDamageCap) must survive into runSingleBattle;\r\n\t\t// Monte Carlo knobs are still read from the original battleInput before cloning.\r\n\t\toptions: battleInput.options,\r\n\t\theroHasDied: battleInput.heroHasDied,\r\n\t\tdebugState: battleInput.debugState,\r\n\t} as BgsBattleInfo;\r\n\treturn inputReady;\r\n};\r\n\r\nconst buildFinalInputForPlayer = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tanomalies: readonly string[],\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tentityIdContainer: { entityId: number },\r\n): { board: BoardEntity[]; hand: BoardEntity[]; player: BgsPlayerEntity } => {\r\n\tif (!playerInfo) {\r\n\t\treturn { board: [], hand: [], player: null };\r\n\t}\r\n\r\n\tconst { board, hand } = buildFinalInputBoard(playerInfo, isPlayer, cardsData, cards);\r\n\tconst isGhost = playerInfo.player?.hpLeft != null && playerInfo.player.hpLeft <= 0;\r\n\tplayerInfo.player.secrets = (playerInfo.player.secrets ?? playerInfo.secrets)?.filter((e) => !!e?.cardId) ?? [];\r\n\t// Add the scriptDataNum1 only on the start of combat phase, so that it doesn't trigger too soon\r\n\t// Don't do this, as secrets like Fleeting Vigor use this info to tell how much buff it will apply\r\n\t// playerInfo.player.secrets.forEach((secret) => (secret.scriptDataNum1 = 0));\r\n\t// Trinkets don't seem to trigger when facing the ghost\r\n\t// http://replays.firestoneapp.com/?reviewId=4ad32e03-2620-4fb1-8b43-cad55afd30fc&turn=27&action=2\r\n\t// One of the trinkets is Blood Golem Sticker, and no Blood Golem is summoned\r\n\t// Looks like that's not always the case:\r\n\t// http://replays.firestoneapp.com/?reviewId=9958e8d3-4388-4e6f-9b36-35f3a08be2f6&turn=25&action=4\r\n\t// playerInfo.player.trinkets = isGhost ? [] : playerInfo.player.trinkets?.filter((e) => !!e?.cardId) ?? [];\r\n\tconst fixedTrinkets = playerInfo.player.trinkets?.filter((e) => !!e?.cardId);\r\n\tplayerInfo.player.trinkets = (fixedTrinkets ?? []).sort((a, b) => a.entityId - b.entityId);\r\n\tplayerInfo.player.friendly = isPlayer;\r\n\tplayerInfo.player.globalInfo = playerInfo.player.globalInfo ?? {};\r\n\tplayerInfo.player.globalInfo.PirateAttackBonus = playerInfo.player.globalInfo.PirateAttackBonus ?? 0;\r\n\tplayerInfo.player.globalInfo.MechAttackBonus = playerInfo.player.globalInfo.MechAttackBonus ?? 0;\r\n\tplayerInfo.player.heroPowers = playerInfo.player.heroPowers?.length\r\n\t\t? playerInfo.player.heroPowers.map((hp, index) => sanitizeHeroPower(hp, index, playerInfo.player, cards))\r\n\t\t: [\r\n\t\t\t\t{\r\n\t\t\t\t\tcardId: playerInfo.player.heroPowerId,\r\n\t\t\t\t\tentityId: playerInfo.player.heroPowerEntityId,\r\n\t\t\t\t\tused: playerInfo.player.heroPowerUsed,\r\n\t\t\t\t\tinfo: playerInfo.player.heroPowerInfo,\r\n\t\t\t\t\tinfo2: playerInfo.player.heroPowerInfo2,\r\n\t\t\t\t} as BgsHeroPower,\r\n\t\t ];\r\n\t// playerInfo.player.heroPowerId =\r\n\t// \tplayerInfo.player.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(playerInfo.player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? playerInfo.player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \tplayerInfo.player.heroPowerId;\r\n\tplayerInfo.player.cardId = isGhost ? CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad : playerInfo.player.cardId;\r\n\tplayerInfo.player.hpLeft = Math.max(1, playerInfo.player.hpLeft);\r\n\t// When using the simulator, the aura is not applied when receiving the board state.\r\n\tsetMissingAuras(board, playerInfo.player, anomalies, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, cardsData, isPlayer, entityIdContainer);\r\n\treturn { board, hand, player: playerInfo.player };\r\n};\r\n\r\nconst sanitizeHeroPower = (\r\n\thp: BgsHeroPower,\r\n\tindex: number,\r\n\tplayer: BgsPlayerEntity,\r\n\tcards: AllCardsService,\r\n): BgsHeroPower => {\r\n\treturn hp;\r\n\t// FIXME: fix this when the situation presents itself. At the moment, we already have trinkets / hero powers / quest rewards\r\n\t// handled separately, so maybe there is no need to map a quest reward to one of Sire D.'s hero power\r\n\t// if (index !== 0) {\r\n\t// \treturn hp;\r\n\t// }\r\n\r\n\t// hp.cardId =\r\n\t// \tplayer.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \thp.cardId;\r\n\t// return hp;\r\n};\r\n\r\nconst sanitizeEntity = (\r\n\tentity: BoardEntity,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n\tapplyDefaultScriptData: boolean,\r\n): BoardEntity => {\r\n\tconst fixed = fixEnchantments(entity, cards);\r\n\tfixed.inInitialState = true;\r\n\tif (applyDefaultScriptData) {\r\n\t\tfixed.scriptDataNum1 = cardsData.defaultScriptDataNum(fixed.cardId) || fixed.scriptDataNum1;\r\n\t}\r\n\taddImpliedMechanics(fixed, cardsData);\r\n\tfixed.friendly = isPlayer;\r\n\treturn fixed;\r\n};\r\n\r\nconst buildFinalInputBoard = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n): { board: BoardEntity[]; hand: BoardEntity[] } => {\r\n\tconst board = playerInfo.board.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, true));\r\n\tconst hand =\r\n\t\tplayerInfo.player.hand?.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, false)) ?? [];\r\n\treturn { board, hand };\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"input-sanitation.js","sourceRoot":"","sources":["../src/input-sanitation.ts"],"names":[],"mappings":"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","sourcesContent":["import { AllCardsService } from '@firestone-hs/reference-data';\r\nimport { BgsBattleInfo } from './bgs-battle-info';\r\nimport { BgsBoardInfo } from './bgs-board-info';\r\nimport { BgsHeroPower, BgsPlayerEntity } from './bgs-player-entity';\r\nimport { BoardEntity } from './board-entity';\r\nimport { CardsData } from './cards/cards-data';\r\nimport { CardIds } from './services/card-ids';\r\nimport { setImplicitDataHero, setMissingAuras } from './simulation/auras';\r\nimport { fixEnchantments } from './simulation/enchantments';\r\nimport { addImpliedMechanics } from './utils';\r\n\r\nexport const buildFinalInput = (\r\n\tbattleInput: BgsBattleInfo,\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n): BgsBattleInfo => {\r\n\tconst entityIdContainer = { entityId: 999_999_999 };\r\n\r\n\tconst {\r\n\t\tboard: playerBoard,\r\n\t\thand: playerHand,\r\n\t\tplayer: playerEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: playerTeammateBoard,\r\n\t\thand: playerTeammateHand,\r\n\t\tplayer: playerTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.playerTeammateBoard,\r\n\t\ttrue,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\tconst {\r\n\t\tboard: opponentBoard,\r\n\t\thand: opponentHand,\r\n\t\tplayer: opponentEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\tconst {\r\n\t\tboard: opponentTeammateBoard,\r\n\t\thand: opponentTeammateHand,\r\n\t\tplayer: opponentTeammateEntity,\r\n\t} = buildFinalInputForPlayer(\r\n\t\tbattleInput.opponentTeammateBoard,\r\n\t\tfalse,\r\n\t\tbattleInput.gameState.anomalies,\r\n\t\tcards,\r\n\t\tcardsData,\r\n\t\tentityIdContainer,\r\n\t);\r\n\r\n\t// We do this so that we can have mutated objects inside the simulation and still\r\n\t// be able to start from a fresh copy for each simulation\r\n\tconst inputReady: BgsBattleInfo = {\r\n\t\tplayerBoard: {\r\n\t\t\tboard: playerBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...playerEntity,\r\n\t\t\t\thand: playerHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\tplayerTeammateBoard: !!playerTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: playerTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...playerTeammateEntity,\r\n\t\t\t\t\t\thand: playerTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\topponentBoard: {\r\n\t\t\tboard: opponentBoard,\r\n\t\t\tplayer: {\r\n\t\t\t\t...opponentEntity,\r\n\t\t\t\thand: opponentHand,\r\n\t\t\t},\r\n\t\t},\r\n\t\topponentTeammateBoard: !!opponentTeammateEntity\r\n\t\t\t? {\r\n\t\t\t\t\tboard: opponentTeammateBoard,\r\n\t\t\t\t\tplayer: {\r\n\t\t\t\t\t\t...opponentTeammateEntity,\r\n\t\t\t\t\t\thand: opponentTeammateHand,\r\n\t\t\t\t\t},\r\n\t\t\t }\r\n\t\t\t: null,\r\n\t\tgameState: {\r\n\t\t\t...battleInput.gameState,\r\n\t\t\tanomalies: battleInput.gameState.anomalies?.filter((a) => !!a) ?? ([] as readonly string[]),\r\n\t\t},\r\n\t\t// Combat-affecting options (e.g. applyDamageCap) must survive into runSingleBattle;\r\n\t\t// Monte Carlo knobs are still read from the original battleInput before cloning.\r\n\t\toptions: battleInput.options,\r\n\t\theroHasDied: battleInput.heroHasDied,\r\n\t\tdebugState: battleInput.debugState,\r\n\t} as BgsBattleInfo;\r\n\treturn inputReady;\r\n};\r\n\r\nconst buildFinalInputForPlayer = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tanomalies: readonly string[],\r\n\tcards: AllCardsService,\r\n\tcardsData: CardsData,\r\n\tentityIdContainer: { entityId: number },\r\n): { board: BoardEntity[]; hand: BoardEntity[]; player: BgsPlayerEntity } => {\r\n\tif (!playerInfo) {\r\n\t\treturn { board: [], hand: [], player: null };\r\n\t}\r\n\r\n\tconst { board, hand } = buildFinalInputBoard(playerInfo, isPlayer, cardsData, cards);\r\n\tconst isGhost = playerInfo.player?.hpLeft != null && playerInfo.player.hpLeft <= 0;\r\n\tplayerInfo.player.secrets = (playerInfo.player.secrets ?? playerInfo.secrets)?.filter((e) => !!e?.cardId) ?? [];\r\n\t// Add the scriptDataNum1 only on the start of combat phase, so that it doesn't trigger too soon\r\n\t// Don't do this, as secrets like Fleeting Vigor use this info to tell how much buff it will apply\r\n\t// playerInfo.player.secrets.forEach((secret) => (secret.scriptDataNum1 = 0));\r\n\t// Trinkets don't seem to trigger when facing the ghost\r\n\t// http://replays.firestoneapp.com/?reviewId=4ad32e03-2620-4fb1-8b43-cad55afd30fc&turn=27&action=2\r\n\t// One of the trinkets is Blood Golem Sticker, and no Blood Golem is summoned\r\n\t// Looks like that's not always the case:\r\n\t// http://replays.firestoneapp.com/?reviewId=9958e8d3-4388-4e6f-9b36-35f3a08be2f6&turn=25&action=4\r\n\t// playerInfo.player.trinkets = isGhost ? [] : playerInfo.player.trinkets?.filter((e) => !!e?.cardId) ?? [];\r\n\tconst fixedTrinkets = playerInfo.player.trinkets?.filter((e) => !!e?.cardId);\r\n\tplayerInfo.player.trinkets = (fixedTrinkets ?? []).sort((a, b) => a.entityId - b.entityId);\r\n\tplayerInfo.player.friendly = isPlayer;\r\n\tplayerInfo.player.globalInfo = playerInfo.player.globalInfo ?? {};\r\n\tplayerInfo.player.globalInfo.PirateAttackBonus = playerInfo.player.globalInfo.PirateAttackBonus ?? 0;\r\n\tplayerInfo.player.globalInfo.MechAttackBonus = playerInfo.player.globalInfo.MechAttackBonus ?? 0;\r\n\tplayerInfo.player.heroPowers = playerInfo.player.heroPowers?.length\r\n\t\t? playerInfo.player.heroPowers.map((hp, index) => sanitizeHeroPower(hp, index, playerInfo.player, cards))\r\n\t\t: [\r\n\t\t\t\t{\r\n\t\t\t\t\tcardId: playerInfo.player.heroPowerId,\r\n\t\t\t\t\tentityId: playerInfo.player.heroPowerEntityId,\r\n\t\t\t\t\tused: playerInfo.player.heroPowerUsed,\r\n\t\t\t\t\tinfo: playerInfo.player.heroPowerInfo,\r\n\t\t\t\t\tinfo2: playerInfo.player.heroPowerInfo2,\r\n\t\t\t\t} as BgsHeroPower,\r\n\t\t ];\r\n\t// playerInfo.player.heroPowerId =\r\n\t// \tplayerInfo.player.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(playerInfo.player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? playerInfo.player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \tplayerInfo.player.heroPowerId;\r\n\tplayerInfo.player.cardId = isGhost ? CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad : playerInfo.player.cardId;\r\n\tplayerInfo.player.hpLeft = Math.max(1, playerInfo.player.hpLeft);\r\n\t// When using the simulator, the aura is not applied when receiving the board state.\r\n\tsetMissingAuras(board, playerInfo.player, anomalies, cards);\r\n\t// Avenge, maxHealth, etc.\r\n\t// setImplicitData(playerBoard, cardsData);\r\n\t// setImplicitData(opponentBoard, cardsData);\r\n\t// Avenge, globalInfo\r\n\tsetImplicitDataHero(playerInfo.player, cardsData, isPlayer, entityIdContainer);\r\n\treturn { board, hand, player: playerInfo.player };\r\n};\r\n\r\nconst sanitizeHeroPower = (\r\n\thp: BgsHeroPower,\r\n\tindex: number,\r\n\tplayer: BgsPlayerEntity,\r\n\tcards: AllCardsService,\r\n): BgsHeroPower => {\r\n\treturn hp;\r\n\t// FIXME: fix this when the situation presents itself. At the moment, we already have trinkets / hero powers / quest rewards\r\n\t// handled separately, so maybe there is no need to map a quest reward to one of Sire D.'s hero power\r\n\t// if (index !== 0) {\r\n\t// \treturn hp;\r\n\t// }\r\n\r\n\t// hp.cardId =\r\n\t// \tplayer.trinkets.find((t) => t.scriptDataNum6 === 3)?.cardId ??\r\n\t// \t(normalizeHeroCardId(player.cardId, cards) === CardIds.SireDenathrius_BG24_HERO_100\r\n\t// \t\t? player.questRewardEntities?.[0]?.cardId\r\n\t// \t\t: null) ??\r\n\t// \thp.cardId;\r\n\t// return hp;\r\n};\r\n\r\nconst sanitizeEntity = (\r\n\tentity: BoardEntity,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n\tapplyDefaultScriptData: boolean,\r\n): BoardEntity => {\r\n\tconst fixed = fixEnchantments(entity, cards);\r\n\tfixed.inInitialState = true;\r\n\tif (applyDefaultScriptData) {\r\n\t\tfixed.scriptDataNum1 = cardsData.defaultScriptDataNum(fixed.cardId) || fixed.scriptDataNum1;\r\n\t}\r\n\taddImpliedMechanics(fixed, cardsData);\r\n\tfixed.friendly = isPlayer;\r\n\t// Used for Persisting Horror\r\n\tfixed.hadVenomous = fixed.venomous;\r\n\treturn fixed;\r\n};\r\n\r\nconst buildFinalInputBoard = (\r\n\tplayerInfo: BgsBoardInfo,\r\n\tisPlayer: boolean,\r\n\tcardsData: CardsData,\r\n\tcards: AllCardsService,\r\n): { board: BoardEntity[]; hand: BoardEntity[] } => {\r\n\tconst board = playerInfo.board.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, true));\r\n\tconst hand =\r\n\t\tplayerInfo.player.hand?.map((entity) => sanitizeEntity(entity, isPlayer, cardsData, cards, false)) ?? [];\r\n\treturn { board, hand };\r\n};\r\n"]}
|