@firestone-hs/simulate-bgs-battle 1.1.757 → 1.1.759
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/battle-info-hash.d.ts +9 -0
- package/dist/battle-info-hash.js +39 -0
- package/dist/battle-info-hash.js.map +1 -0
- package/dist/cards/impl/minion/cthun.js +18 -15
- package/dist/cards/impl/minion/cthun.js.map +1 -1
- package/dist/simulate-bgs-battle.d.ts +1 -0
- package/dist/simulate-bgs-battle.js +9 -5
- package/dist/simulate-bgs-battle.js.map +1 -1
- package/dist/simulation/add-minion-to-board.js +12 -1
- package/dist/simulation/add-minion-to-board.js.map +1 -1
- package/dist/simulation/death-effects.js +8 -2
- package/dist/simulation/death-effects.js.map +1 -1
- package/dist/simulation/deity.d.ts +8 -0
- package/dist/simulation/deity.js +65 -3
- package/dist/simulation/deity.js.map +1 -1
- package/dist/simulation/spectator/game-action.d.ts +1 -0
- package/dist/simulation/spectator/game-action.js +24 -3
- package/dist/simulation/spectator/game-action.js.map +1 -1
- package/dist/simulation/spectator/spectator.js +2 -0
- package/dist/simulation/spectator/spectator.js.map +1 -1
- package/dist/simulation/start-of-combat/start-of-combat.js +3 -0
- package/dist/simulation/start-of-combat/start-of-combat.js.map +1 -1
- package/dist/simulation-result.d.ts +1 -0
- package/dist/simulation-result.js.map +1 -1
- package/package.json +1 -1
package/dist/simulation/deity.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.onFriendlyAberrationDied = exports.buffTeamDeities = exports.incrementDeitySecretStats = exports.buffYourDeity = exports.applyDeityBaseStats = exports.getDeityBaseStats = exports.getOnBoardDeity = exports.getDeitySecret = exports.isAberration = exports.isDeityCard = void 0;
|
|
3
|
+
exports.retryDeityAwakenOnNextAberrationDeath = exports.markDeitySecretTriggered = exports.onFriendlyAberrationDied = exports.buffTeamDeities = exports.incrementDeitySecretStats = exports.buffYourDeity = exports.consumeDeityBaseStatsAssignment = exports.applyDeityBaseStats = exports.stampOnBoardDeityAuras = exports.getDeityAuraSnapshot = exports.getDeityBaseStats = exports.getOnBoardDeity = exports.getDeitySecret = exports.isAberration = exports.isDeityCard = 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 _card_mappings_1 = require("../cards/impl/_card-mappings");
|
|
@@ -24,6 +24,8 @@ const getOnBoardDeity = (board, allCards) => {
|
|
|
24
24
|
return board.find((e) => (0, utils_1.hasEntityMechanic)(e, reference_data_1.GameTag.BACON_OLD_GOD, allCards) && e.health > 0 && !e.definitelyDead);
|
|
25
25
|
};
|
|
26
26
|
exports.getOnBoardDeity = getOnBoardDeity;
|
|
27
|
+
const awakeningSecrets = new WeakSet();
|
|
28
|
+
const deityBaseStatsAssigned = new WeakSet();
|
|
27
29
|
const readSecretAttack = (secret) => {
|
|
28
30
|
var _a, _b, _c;
|
|
29
31
|
return (_c = (_b = (_a = secret.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK]) !== null && _b !== void 0 ? _b : secret.scriptDataNum2) !== null && _c !== void 0 ? _c : 1;
|
|
@@ -48,6 +50,33 @@ const getDeityBaseStats = (hero, entity) => {
|
|
|
48
50
|
return { attack, health };
|
|
49
51
|
};
|
|
50
52
|
exports.getDeityBaseStats = getDeityBaseStats;
|
|
53
|
+
const getDeityAuraSnapshot = (entity, hero) => {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
const attack = (_a = entity.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK];
|
|
56
|
+
const health = (_b = entity.tags) === null || _b === void 0 ? void 0 : _b[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH];
|
|
57
|
+
if (attack != null && health != null) {
|
|
58
|
+
return { attack, health: Math.max(1, health) };
|
|
59
|
+
}
|
|
60
|
+
return (0, exports.getDeityBaseStats)(hero, entity);
|
|
61
|
+
};
|
|
62
|
+
exports.getDeityAuraSnapshot = getDeityAuraSnapshot;
|
|
63
|
+
const stampOnBoardDeityAuras = (board, hero, allCards) => {
|
|
64
|
+
var _a, _b, _c;
|
|
65
|
+
for (const entity of board) {
|
|
66
|
+
if (!(0, exports.isDeityCard)(entity.cardId, allCards)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (((_a = entity.tags) === null || _a === void 0 ? void 0 : _a[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK]) != null &&
|
|
70
|
+
((_b = entity.tags) === null || _b === void 0 ? void 0 : _b[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH]) != null) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const { attack, health } = (0, exports.getDeityBaseStats)(hero, entity);
|
|
74
|
+
entity.tags = (_c = entity.tags) !== null && _c !== void 0 ? _c : {};
|
|
75
|
+
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK] = attack;
|
|
76
|
+
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH] = health;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
exports.stampOnBoardDeityAuras = stampOnBoardDeityAuras;
|
|
51
80
|
const applyDeityBaseStats = (entity, hero) => {
|
|
52
81
|
var _a;
|
|
53
82
|
const { attack, health } = (0, exports.getDeityBaseStats)(hero, entity);
|
|
@@ -58,8 +87,17 @@ const applyDeityBaseStats = (entity, hero) => {
|
|
|
58
87
|
entity.tags = (_a = entity.tags) !== null && _a !== void 0 ? _a : {};
|
|
59
88
|
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_ATTACK] = attack;
|
|
60
89
|
entity.tags[reference_data_1.GameTag.BACON_OLD_GOD_HEALTH] = health;
|
|
90
|
+
deityBaseStatsAssigned.add(entity);
|
|
61
91
|
};
|
|
62
92
|
exports.applyDeityBaseStats = applyDeityBaseStats;
|
|
93
|
+
const consumeDeityBaseStatsAssignment = (entity) => {
|
|
94
|
+
if (!deityBaseStatsAssigned.has(entity)) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
deityBaseStatsAssigned.delete(entity);
|
|
98
|
+
return true;
|
|
99
|
+
};
|
|
100
|
+
exports.consumeDeityBaseStatsAssignment = consumeDeityBaseStatsAssignment;
|
|
63
101
|
const buffYourDeity = (hero, board, source, attack, health, gameState) => {
|
|
64
102
|
const onBoard = (0, exports.getOnBoardDeity)(board, gameState.allCards);
|
|
65
103
|
if (onBoard) {
|
|
@@ -102,7 +140,7 @@ const onFriendlyAberrationDied = (deadEntity, _deadEntityIndexFromRight, board,
|
|
|
102
140
|
return [];
|
|
103
141
|
}
|
|
104
142
|
const secret = (0, exports.getDeitySecret)(hero);
|
|
105
|
-
if (!secret || secret.triggered) {
|
|
143
|
+
if (!secret || secret.triggered || awakeningSecrets.has(secret)) {
|
|
106
144
|
return [];
|
|
107
145
|
}
|
|
108
146
|
const remaining = (secret.scriptDataNum1 || 3) - 1;
|
|
@@ -110,7 +148,11 @@ const onFriendlyAberrationDied = (deadEntity, _deadEntityIndexFromRight, board,
|
|
|
110
148
|
if (remaining > 0) {
|
|
111
149
|
return [];
|
|
112
150
|
}
|
|
113
|
-
|
|
151
|
+
if (board.length >= 7) {
|
|
152
|
+
(0, exports.retryDeityAwakenOnNextAberrationDeath)(hero);
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
awakeningSecrets.add(secret);
|
|
114
156
|
const cardId = resolveDeityCardId(secret, gameState);
|
|
115
157
|
const spawns = (0, deathrattle_spawns_1.spawnEntities)(cardId, 1, board, hero, otherBoard, otherHero, gameState, deadEntity.friendly, false, false, true);
|
|
116
158
|
for (const spawn of spawns) {
|
|
@@ -134,7 +176,27 @@ const onFriendlyAberrationDied = (deadEntity, _deadEntityIndexFromRight, board,
|
|
|
134
176
|
});
|
|
135
177
|
}
|
|
136
178
|
}
|
|
179
|
+
if (!spawns.length) {
|
|
180
|
+
secret.triggered = true;
|
|
181
|
+
}
|
|
137
182
|
return [...spawns];
|
|
138
183
|
};
|
|
139
184
|
exports.onFriendlyAberrationDied = onFriendlyAberrationDied;
|
|
185
|
+
const markDeitySecretTriggered = (hero) => {
|
|
186
|
+
const secret = (0, exports.getDeitySecret)(hero);
|
|
187
|
+
if (secret) {
|
|
188
|
+
secret.triggered = true;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
exports.markDeitySecretTriggered = markDeitySecretTriggered;
|
|
192
|
+
const retryDeityAwakenOnNextAberrationDeath = (hero) => {
|
|
193
|
+
const secret = (0, exports.getDeitySecret)(hero);
|
|
194
|
+
if (!secret) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
awakeningSecrets.delete(secret);
|
|
198
|
+
secret.triggered = false;
|
|
199
|
+
secret.scriptDataNum1 = 1;
|
|
200
|
+
};
|
|
201
|
+
exports.retryDeityAwakenOnNextAberrationDeath = retryDeityAwakenOnNextAberrationDeath;
|
|
140
202
|
//# sourceMappingURL=deity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deity.js","sourceRoot":"","sources":["../../src/simulation/deity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Deity / BG_OldGod secret.\r\n * After 3 friendly Aberrations die each combat, awaken C'Thun or Y'Shaarj with stored stats.\r\n * scriptDataNum1 = deaths remaining, tags BACON_OLD_GOD_ATTACK/HEALTH = atk/hp, scriptDataNum6 = deity dbfId.\r\n */\r\nimport { AllCardsService, GameTag, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { hasOnAwaken } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { getPlayerState, hasCorrectTribe, hasEntityMechanic, hasMechanic } from '../utils';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const isDeityCard = (cardId: string, allCards: AllCardsService): boolean => {\r\n\treturn hasMechanic(allCards.getCard(cardId), GameTag.BACON_OLD_GOD);\r\n};\r\n\r\nexport const isAberration = (entity: BoardEntity, hero: BgsPlayerEntity, gameState: FullGameState): boolean => {\r\n\treturn hasCorrectTribe(entity, hero, Race.ABERRATION, gameState.anomalies, gameState.allCards);\r\n};\r\n\r\nexport const getDeitySecret = (hero: BgsPlayerEntity): BoardSecret | undefined => {\r\n\treturn hero.secrets?.find((s) => s.cardId === CardIds.SecretDeityDnt_BG_OldGod);\r\n};\r\n\r\nexport const getOnBoardDeity = (board: BoardEntity[], allCards: AllCardsService): BoardEntity | undefined => {\r\n\treturn board.find(\r\n\t\t(e) => hasEntityMechanic(e, GameTag.BACON_OLD_GOD, allCards) && e.health > 0 && !e.definitelyDead,\r\n\t);\r\n};\r\n\r\nconst readSecretAttack = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ?? secret.scriptDataNum2 ?? 1;\r\n};\r\n\r\nconst readSecretHealth = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ?? secret.scriptDataNum3 ?? 1;\r\n};\r\n\r\nconst writeSecretStats = (secret: BoardSecret, attack: number, health: number): void => {\r\n\tsecret.scriptDataNum2 = attack;\r\n\tsecret.scriptDataNum3 = health;\r\n\tsecret.tags = secret.tags ?? {};\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n};\r\n\r\nexport const getDeityBaseStats = (hero: BgsPlayerEntity, entity?: BoardEntity): { attack: number; health: number } => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tconst attack =\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tsecret?.scriptDataNum2 ??\r\n\t\t1;\r\n\tconst health = Math.max(\r\n\t\t1,\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tsecret?.scriptDataNum3 ??\r\n\t\t\t1,\r\n\t);\r\n\treturn { attack, health };\r\n};\r\n\r\nexport const applyDeityBaseStats = (entity: BoardEntity, hero: BgsPlayerEntity): void => {\r\n\tconst { attack, health } = getDeityBaseStats(hero, entity);\r\n\tentity.attack = attack;\r\n\tentity.maxAttack = attack;\r\n\tentity.health = health;\r\n\tentity.maxHealth = health;\r\n\tentity.tags = entity.tags ?? {};\r\n\tentity.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tentity.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n};\r\n\r\nexport const buffYourDeity = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity | BoardSecret | BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst onBoard = getOnBoardDeity(board, gameState.allCards);\r\n\tif (onBoard) {\r\n\t\tmodifyStats(onBoard, source as BoardEntity, attack, health, board, hero, gameState);\r\n\t}\r\n\tincrementDeitySecretStats(hero, attack, health);\r\n};\r\n\r\nexport const incrementDeitySecretStats = (hero: BgsPlayerEntity, attack: number, health: number): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (secret) {\r\n\t\twriteSecretStats(secret, readSecretAttack(secret) + attack, readSecretHealth(secret) + health);\r\n\t}\r\n};\r\n\r\nexport const buffTeamDeities = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tbuffYourDeity(hero, board, source, attack, health, gameState);\r\n\tconst playerState = getPlayerState(gameState.gameState, hero);\r\n\tconst teammate = playerState?.teammate;\r\n\tif (teammate?.player) {\r\n\t\tbuffYourDeity(teammate.player, teammate.board ?? [], source, attack, health, gameState);\r\n\t}\r\n};\r\n\r\nconst resolveDeityCardId = (secret: BoardSecret, gameState: FullGameState): string => {\r\n\tconst dbfId = secret.scriptDataNum6 ?? secret.tags?.[GameTag.BACON_GLOBAL_OLD_GOD_DBID];\r\n\tif (dbfId) {\r\n\t\tconst fromDbf = gameState.allCards.getCardFromDbfId(dbfId);\r\n\t\tif (fromDbf?.id) {\r\n\t\t\treturn fromDbf.id;\r\n\t\t}\r\n\t}\r\n\treturn CardIds.Cthun_BGFYM_000;\r\n};\r\n\r\nexport const onFriendlyAberrationDied = (\r\n\tdeadEntity: BoardEntity,\r\n\t_deadEntityIndexFromRight: number,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): BoardEntity[] => {\r\n\tif (!isAberration(deadEntity, hero, gameState)) {\r\n\t\treturn [];\r\n\t}\r\n\t// 2026-09-22: This seems to be an HS bug, but for now the deity doesn't spawn when facing the ghost\r\n\t// Looks like this is an intermittent bug\r\n\t// if (hero.hpLeft <= 0 || hero.cardId === CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad) {\r\n\t// \treturn [];\r\n\t// }\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (!secret || secret.triggered) {\r\n\t\treturn [];\r\n\t}\r\n\tconst remaining = (secret.scriptDataNum1 || 3) - 1;\r\n\tsecret.scriptDataNum1 = remaining;\r\n\tif (remaining > 0) {\r\n\t\treturn [];\r\n\t}\r\n\tsecret.triggered = true;\r\n\tconst cardId = resolveDeityCardId(secret, gameState);\r\n\tconst spawns = spawnEntities(\r\n\t\tcardId,\r\n\t\t1,\r\n\t\tboard,\r\n\t\thero,\r\n\t\totherBoard,\r\n\t\totherHero,\r\n\t\tgameState,\r\n\t\tdeadEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t);\r\n\tfor (const spawn of spawns) {\r\n\t\tapplyDeityBaseStats(spawn, hero);\r\n\t\tif (hero.trinkets?.some((t) => t.cardId === CardIds.EvilExperiment_BG36_MagicItem_416)) {\r\n\t\t\tspawn.reborn = true;\r\n\t\t}\r\n\t}\r\n\tif (spawns[0]) {\r\n\t\tgameState.spectator.registerPowerTarget(secret, spawns[0], board, hero, otherHero);\r\n\t}\r\n\tfor (const spawn of spawns) {\r\n\t\tconst impl = cardMappings[spawn.cardId];\r\n\t\tif (hasOnAwaken(impl)) {\r\n\t\t\timpl.onAwaken(spawn, {\r\n\t\t\t\thero,\r\n\t\t\t\tboard,\r\n\t\t\t\totherHero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\tgameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\treturn [...spawns];\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"deity.js","sourceRoot":"","sources":["../../src/simulation/deity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Deity / BG_OldGod secret.\r\n * After 3 friendly Aberrations die each combat, awaken C'Thun or Y'Shaarj with stored stats.\r\n * scriptDataNum1 = deaths remaining, tags BACON_OLD_GOD_ATTACK/HEALTH = atk/hp, scriptDataNum6 = deity dbfId.\r\n */\r\nimport { AllCardsService, GameTag, Race } from '@firestone-hs/reference-data';\r\nimport { BgsPlayerEntity } from '../bgs-player-entity';\r\nimport { BoardEntity } from '../board-entity';\r\nimport { BoardSecret } from '../board-secret';\r\nimport { hasOnAwaken } from '../cards/card.interface';\r\nimport { cardMappings } from '../cards/impl/_card-mappings';\r\nimport { CardIds } from '../services/card-ids';\r\nimport { getPlayerState, hasCorrectTribe, hasEntityMechanic, hasMechanic } from '../utils';\r\nimport { spawnEntities } from './deathrattle-spawns';\r\nimport { FullGameState } from './internal-game-state';\r\nimport { modifyStats } from './stats';\r\n\r\nexport const isDeityCard = (cardId: string, allCards: AllCardsService): boolean => {\r\n\treturn hasMechanic(allCards.getCard(cardId), GameTag.BACON_OLD_GOD);\r\n};\r\n\r\nexport const isAberration = (entity: BoardEntity, hero: BgsPlayerEntity, gameState: FullGameState): boolean => {\r\n\treturn hasCorrectTribe(entity, hero, Race.ABERRATION, gameState.anomalies, gameState.allCards);\r\n};\r\n\r\nexport const getDeitySecret = (hero: BgsPlayerEntity): BoardSecret | undefined => {\r\n\treturn hero.secrets?.find((s) => s.cardId === CardIds.SecretDeityDnt_BG_OldGod);\r\n};\r\n\r\nexport const getOnBoardDeity = (board: BoardEntity[], allCards: AllCardsService): BoardEntity | undefined => {\r\n\treturn board.find(\r\n\t\t(e) => hasEntityMechanic(e, GameTag.BACON_OLD_GOD, allCards) && e.health > 0 && !e.definitelyDead,\r\n\t);\r\n};\r\n\r\nconst awakeningSecrets = new WeakSet<BoardSecret>();\r\n/** Entities whose attack/health were just set to the stored aura. The next aura pass must not add them again. */\r\nconst deityBaseStatsAssigned = new WeakSet<BoardEntity>();\r\n\r\nconst readSecretAttack = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ?? secret.scriptDataNum2 ?? 1;\r\n};\r\n\r\nconst readSecretHealth = (secret: BoardSecret): number => {\r\n\treturn secret.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ?? secret.scriptDataNum3 ?? 1;\r\n};\r\n\r\nconst writeSecretStats = (secret: BoardSecret, attack: number, health: number): void => {\r\n\tsecret.scriptDataNum2 = attack;\r\n\tsecret.scriptDataNum3 = health;\r\n\tsecret.tags = secret.tags ?? {};\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tsecret.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n};\r\n\r\nexport const getDeityBaseStats = (hero: BgsPlayerEntity, entity?: BoardEntity): { attack: number; health: number } => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tconst attack =\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_ATTACK] ??\r\n\t\tsecret?.scriptDataNum2 ??\r\n\t\t1;\r\n\tconst health = Math.max(\r\n\t\t1,\r\n\t\tsecret?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tentity?.tags?.[GameTag.BACON_OLD_GOD_HEALTH] ??\r\n\t\t\tsecret?.scriptDataNum3 ??\r\n\t\t\t1,\r\n\t);\r\n\treturn { attack, health };\r\n};\r\n\r\n/** Aura captured when this minion was summoned. Later secret growth is a separate buff. */\r\nexport const getDeityAuraSnapshot = (\r\n\tentity: BoardEntity,\r\n\thero: BgsPlayerEntity,\r\n): { attack: number; health: number } => {\r\n\tconst attack = entity.tags?.[GameTag.BACON_OLD_GOD_ATTACK];\r\n\tconst health = entity.tags?.[GameTag.BACON_OLD_GOD_HEALTH];\r\n\tif (attack != null && health != null) {\r\n\t\treturn { attack, health: Math.max(1, health) };\r\n\t}\r\n\treturn getDeityBaseStats(hero, entity);\r\n};\r\n\r\n/** Freeze the current secret onto a deity that is already in play, before combat buffs change it. */\r\nexport const stampOnBoardDeityAuras = (\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\tallCards: AllCardsService,\r\n): void => {\r\n\tfor (const entity of board) {\r\n\t\tif (!isDeityCard(entity.cardId, allCards)) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (\r\n\t\t\tentity.tags?.[GameTag.BACON_OLD_GOD_ATTACK] != null &&\r\n\t\t\tentity.tags?.[GameTag.BACON_OLD_GOD_HEALTH] != null\r\n\t\t) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tconst { attack, health } = getDeityBaseStats(hero, entity);\r\n\t\tentity.tags = entity.tags ?? {};\r\n\t\tentity.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\t\tentity.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n\t}\r\n};\r\n\r\nexport const applyDeityBaseStats = (entity: BoardEntity, hero: BgsPlayerEntity): void => {\r\n\tconst { attack, health } = getDeityBaseStats(hero, entity);\r\n\tentity.attack = attack;\r\n\tentity.maxAttack = attack;\r\n\tentity.health = health;\r\n\tentity.maxHealth = health;\r\n\tentity.tags = entity.tags ?? {};\r\n\tentity.tags[GameTag.BACON_OLD_GOD_ATTACK] = attack;\r\n\tentity.tags[GameTag.BACON_OLD_GOD_HEALTH] = health;\r\n\tdeityBaseStatsAssigned.add(entity);\r\n};\r\n\r\n/** True once, for the aura pass that follows a fresh stat assignment (awaken, reborn). */\r\nexport const consumeDeityBaseStatsAssignment = (entity: BoardEntity): boolean => {\r\n\tif (!deityBaseStatsAssigned.has(entity)) {\r\n\t\treturn false;\r\n\t}\r\n\tdeityBaseStatsAssigned.delete(entity);\r\n\treturn true;\r\n};\r\n\r\nexport const buffYourDeity = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity | BoardSecret | BgsPlayerEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tconst onBoard = getOnBoardDeity(board, gameState.allCards);\r\n\tif (onBoard) {\r\n\t\tmodifyStats(onBoard, source as BoardEntity, attack, health, board, hero, gameState);\r\n\t}\r\n\tincrementDeitySecretStats(hero, attack, health);\r\n};\r\n\r\nexport const incrementDeitySecretStats = (hero: BgsPlayerEntity, attack: number, health: number): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (secret) {\r\n\t\twriteSecretStats(secret, readSecretAttack(secret) + attack, readSecretHealth(secret) + health);\r\n\t}\r\n};\r\n\r\nexport const buffTeamDeities = (\r\n\thero: BgsPlayerEntity,\r\n\tboard: BoardEntity[],\r\n\tsource: BoardEntity,\r\n\tattack: number,\r\n\thealth: number,\r\n\tgameState: FullGameState,\r\n): void => {\r\n\tbuffYourDeity(hero, board, source, attack, health, gameState);\r\n\tconst playerState = getPlayerState(gameState.gameState, hero);\r\n\tconst teammate = playerState?.teammate;\r\n\tif (teammate?.player) {\r\n\t\tbuffYourDeity(teammate.player, teammate.board ?? [], source, attack, health, gameState);\r\n\t}\r\n};\r\n\r\nconst resolveDeityCardId = (secret: BoardSecret, gameState: FullGameState): string => {\r\n\tconst dbfId = secret.scriptDataNum6 ?? secret.tags?.[GameTag.BACON_GLOBAL_OLD_GOD_DBID];\r\n\tif (dbfId) {\r\n\t\tconst fromDbf = gameState.allCards.getCardFromDbfId(dbfId);\r\n\t\tif (fromDbf?.id) {\r\n\t\t\treturn fromDbf.id;\r\n\t\t}\r\n\t}\r\n\treturn CardIds.Cthun_BGFYM_000;\r\n};\r\n\r\nexport const onFriendlyAberrationDied = (\r\n\tdeadEntity: BoardEntity,\r\n\t_deadEntityIndexFromRight: number,\r\n\tboard: BoardEntity[],\r\n\thero: BgsPlayerEntity,\r\n\totherBoard: BoardEntity[],\r\n\totherHero: BgsPlayerEntity,\r\n\tgameState: FullGameState,\r\n): BoardEntity[] => {\r\n\tif (!isAberration(deadEntity, hero, gameState)) {\r\n\t\treturn [];\r\n\t}\r\n\t// 2026-09-22: This seems to be an HS bug, but for now the deity doesn't spawn when facing the ghost\r\n\t// Looks like this is an intermittent bug\r\n\t// if (hero.hpLeft <= 0 || hero.cardId === CardIds.Kelthuzad_TB_BaconShop_HERO_KelThuzad) {\r\n\t// \treturn [];\r\n\t// }\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (!secret || secret.triggered || awakeningSecrets.has(secret)) {\r\n\t\treturn [];\r\n\t}\r\n\tconst remaining = (secret.scriptDataNum1 || 3) - 1;\r\n\tsecret.scriptDataNum1 = remaining;\r\n\tif (remaining > 0) {\r\n\t\treturn [];\r\n\t}\r\n\t// A full board skips this awaken. The next friendly Aberration death tries again.\r\n\tif (board.length >= 7) {\r\n\t\tretryDeityAwakenOnNextAberrationDeath(hero);\r\n\t\treturn [];\r\n\t}\r\n\t// Keep the secret visible in the replay until the summon action is recorded.\r\n\tawakeningSecrets.add(secret);\r\n\tconst cardId = resolveDeityCardId(secret, gameState);\r\n\tconst spawns = spawnEntities(\r\n\t\tcardId,\r\n\t\t1,\r\n\t\tboard,\r\n\t\thero,\r\n\t\totherBoard,\r\n\t\totherHero,\r\n\t\tgameState,\r\n\t\tdeadEntity.friendly,\r\n\t\tfalse,\r\n\t\tfalse,\r\n\t\ttrue,\r\n\t);\r\n\tfor (const spawn of spawns) {\r\n\t\tapplyDeityBaseStats(spawn, hero);\r\n\t\tif (hero.trinkets?.some((t) => t.cardId === CardIds.EvilExperiment_BG36_MagicItem_416)) {\r\n\t\t\tspawn.reborn = true;\r\n\t\t}\r\n\t}\r\n\tif (spawns[0]) {\r\n\t\tgameState.spectator.registerPowerTarget(secret, spawns[0], board, hero, otherHero);\r\n\t}\r\n\tfor (const spawn of spawns) {\r\n\t\tconst impl = cardMappings[spawn.cardId];\r\n\t\tif (hasOnAwaken(impl)) {\r\n\t\t\timpl.onAwaken(spawn, {\r\n\t\t\t\thero,\r\n\t\t\t\tboard,\r\n\t\t\t\totherHero,\r\n\t\t\t\totherBoard,\r\n\t\t\t\tgameState,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\tif (!spawns.length) {\r\n\t\tsecret.triggered = true;\r\n\t}\r\n\treturn [...spawns];\r\n};\r\n\r\nexport const markDeitySecretTriggered = (hero: BgsPlayerEntity): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (secret) {\r\n\t\tsecret.triggered = true;\r\n\t}\r\n};\r\n\r\n/** Board was full, so this awaken did not happen. The next Aberration death starts the summon again. */\r\nexport const retryDeityAwakenOnNextAberrationDeath = (hero: BgsPlayerEntity): void => {\r\n\tconst secret = getDeitySecret(hero);\r\n\tif (!secret) {\r\n\t\treturn;\r\n\t}\r\n\tawakeningSecrets.delete(secret);\r\n\tsecret.triggered = false;\r\n\tsecret.scriptDataNum1 = 1;\r\n};\r\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BgsHeroPower, BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';
|
|
2
2
|
import { BoardEntity } from '../../board-entity';
|
|
3
3
|
import { BoardSecret } from '../../board-secret';
|
|
4
|
+
export declare const copySecrets: (secrets: readonly BoardSecret[] | undefined) => readonly BoardSecret[] | undefined;
|
|
4
5
|
export interface GameAction {
|
|
5
6
|
type: 'damage' | 'attack' | 'spawn' | 'minion-death' | 'power-target' | 'start-of-combat' | 'player-attack' | 'opponent-attack';
|
|
6
7
|
playerBoard: readonly BoardEntity[];
|
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildGameAction = void 0;
|
|
3
|
+
exports.buildGameAction = exports.copySecrets = void 0;
|
|
4
4
|
const resolve_trinket_hero_power_1 = require("./resolve-trinket-hero-power");
|
|
5
|
+
const copySecrets = (secrets) => {
|
|
6
|
+
if (!secrets) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
return secrets.map((secret) => ({
|
|
10
|
+
entityId: secret.entityId,
|
|
11
|
+
cardId: secret.cardId,
|
|
12
|
+
triggered: secret.triggered,
|
|
13
|
+
scriptDataNum1: secret.scriptDataNum1,
|
|
14
|
+
scriptDataNum2: secret.scriptDataNum2,
|
|
15
|
+
scriptDataNum3: secret.scriptDataNum3,
|
|
16
|
+
scriptDataNum6: secret.scriptDataNum6,
|
|
17
|
+
triggersLeft: secret.triggersLeft,
|
|
18
|
+
tags: secret.tags ? { ...secret.tags } : undefined,
|
|
19
|
+
}));
|
|
20
|
+
};
|
|
21
|
+
exports.copySecrets = copySecrets;
|
|
5
22
|
const buildGameAction = (playerHero, opponentHero, action) => {
|
|
6
23
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15;
|
|
7
24
|
const isPlayerSireD = (_a = playerHero === null || playerHero === void 0 ? void 0 : playerHero.cardId) === null || _a === void 0 ? void 0 : _a.startsWith("BG24_HERO_100");
|
|
8
25
|
const isOpponentSireD = (_b = opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.cardId) === null || _b === void 0 ? void 0 : _b.startsWith("BG24_HERO_100");
|
|
9
26
|
const result = {
|
|
10
27
|
...action,
|
|
11
|
-
playerSecrets:
|
|
28
|
+
playerSecrets: playerHero
|
|
29
|
+
? (0, exports.copySecrets)(((_c = playerHero.secrets) !== null && _c !== void 0 ? _c : []).filter((s) => !s.triggered))
|
|
30
|
+
: undefined,
|
|
12
31
|
playerCardId: playerHero === null || playerHero === void 0 ? void 0 : playerHero.cardId,
|
|
13
32
|
playerEntityId: playerHero === null || playerHero === void 0 ? void 0 : playerHero.entityId,
|
|
14
33
|
playerHeroPowerCardId: (_g = (_d = (0, resolve_trinket_hero_power_1.resolveTrinketHeroPowerCardId)(playerHero === null || playerHero === void 0 ? void 0 : playerHero.trinkets)) !== null && _d !== void 0 ? _d : (isPlayerSireD ? (_f = (_e = playerHero.questRewardEntities) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.cardId : null)) !== null && _g !== void 0 ? _g : (_h = playerHero === null || playerHero === void 0 ? void 0 : playerHero.heroPowers[0]) === null || _h === void 0 ? void 0 : _h.cardId,
|
|
@@ -25,7 +44,9 @@ const buildGameAction = (playerHero, opponentHero, action) => {
|
|
|
25
44
|
? null
|
|
26
45
|
: (_w = (_v = (_u = playerHero === null || playerHero === void 0 ? void 0 : playerHero.questRewardEntities) === null || _u === void 0 ? void 0 : _u[0]) === null || _v === void 0 ? void 0 : _v.scriptDataNum1) !== null && _w !== void 0 ? _w : 0,
|
|
27
46
|
playerTrinkets: playerHero === null || playerHero === void 0 ? void 0 : playerHero.trinkets,
|
|
28
|
-
opponentSecrets:
|
|
47
|
+
opponentSecrets: opponentHero
|
|
48
|
+
? (0, exports.copySecrets)(((_x = opponentHero.secrets) !== null && _x !== void 0 ? _x : []).filter((s) => !s.triggered))
|
|
49
|
+
: undefined,
|
|
29
50
|
opponentCardId: opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.cardId,
|
|
30
51
|
opponentEntityId: opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.entityId,
|
|
31
52
|
opponentHeroPowerCardId: (_3 = (_1 = (_y = (0, resolve_trinket_hero_power_1.resolveTrinketHeroPowerCardId)(opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.trinkets)) !== null && _y !== void 0 ? _y : (isOpponentSireD ? (_0 = (_z = opponentHero.questRewardEntities) === null || _z === void 0 ? void 0 : _z[0]) === null || _0 === void 0 ? void 0 : _0.cardId : null)) !== null && _1 !== void 0 ? _1 : (_2 = opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.heroPowers[0]) === null || _2 === void 0 ? void 0 : _2.cardId) !== null && _3 !== void 0 ? _3 : opponentHero === null || opponentHero === void 0 ? void 0 : opponentHero.heroPowerId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game-action.js","sourceRoot":"","sources":["../../../src/simulation/spectator/game-action.ts"],"names":[],"mappings":";;;AAIA,6EAA6E;
|
|
1
|
+
{"version":3,"file":"game-action.js","sourceRoot":"","sources":["../../../src/simulation/spectator/game-action.ts"],"names":[],"mappings":"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","sourcesContent":["import { CardIds } from '../../services/card-ids';\r\nimport { BgsHeroPower, BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\nimport { resolveTrinketHeroPowerCardId } from './resolve-trinket-hero-power';\r\n\r\n/** Detach from the live secret. Combat mutates scriptDataNum and tags in place. */\r\nexport const copySecrets = (secrets: readonly BoardSecret[] | undefined): readonly BoardSecret[] | undefined => {\r\n\tif (!secrets) {\r\n\t\treturn undefined;\r\n\t}\r\n\treturn secrets.map((secret) => ({\r\n\t\tentityId: secret.entityId,\r\n\t\tcardId: secret.cardId,\r\n\t\ttriggered: secret.triggered,\r\n\t\tscriptDataNum1: secret.scriptDataNum1,\r\n\t\tscriptDataNum2: secret.scriptDataNum2,\r\n\t\tscriptDataNum3: secret.scriptDataNum3,\r\n\t\tscriptDataNum6: secret.scriptDataNum6,\r\n\t\ttriggersLeft: secret.triggersLeft,\r\n\t\ttags: secret.tags ? { ...secret.tags } : undefined,\r\n\t}));\r\n};\r\n\r\nexport interface GameAction {\r\n\ttype:\r\n\t\t| 'damage'\r\n\t\t| 'attack'\r\n\t\t| 'spawn'\r\n\t\t| 'minion-death'\r\n\t\t| 'power-target'\r\n\t\t| 'start-of-combat'\r\n\t\t| 'player-attack'\r\n\t\t| 'opponent-attack';\r\n\tplayerBoard: readonly BoardEntity[];\r\n\tplayerHand: readonly BoardEntity[];\r\n\tplayerSecrets: readonly BoardSecret[];\r\n\tplayerTrinkets: readonly BoardTrinket[];\r\n\topponentBoard: readonly BoardEntity[];\r\n\topponentHand: readonly BoardEntity[];\r\n\topponentSecrets: readonly BoardSecret[];\r\n\topponentTrinkets: readonly BoardTrinket[];\r\n\tplayerCardId: string;\r\n\tplayerEntityId: number;\r\n\tplayerHeroPowerCardId: string;\r\n\tplayerHeroPowerEntityId: number;\r\n\tplayerHeroPowerUsed: boolean;\r\n\tplayerHeroPowers: readonly BgsHeroPower[];\r\n\topponentCardId: string;\r\n\topponentEntityId: number;\r\n\topponentHeroPowerCardId: string;\r\n\topponentHeroPowerEntityId: number;\r\n\topponentHeroPowerUsed: boolean;\r\n\topponentHeroPowers: readonly BgsHeroPower[];\r\n\tplayerRewardCardId: string;\r\n\tplayerRewardEntityId: number;\r\n\tplayerRewardData: number;\r\n\topponentRewardCardId: string;\r\n\topponentRewardEntityId: number;\r\n\topponentRewardData: number;\r\n\tsourceEntityId?: number;\r\n\t/** @deprecated */\r\n\ttargetEntityId?: number;\r\n\ttargetEntityIds?: number[];\r\n\r\n\tdamages?: Damage[];\r\n\tspawns?: readonly BoardEntity[];\r\n\tdeaths?: readonly BoardEntity[];\r\n\tdeadMinionsPositionsOnBoard?: readonly number[];\r\n}\r\n\r\nexport interface Damage {\r\n\treadonly sourceEntityId?: number;\r\n\treadonly targetEntityId?: number;\r\n\treadonly damage?: number;\r\n}\r\n\r\nexport const buildGameAction = (\r\n\tplayerHero: BgsPlayerEntity,\r\n\topponentHero: BgsPlayerEntity,\r\n\taction: Partial<GameAction>,\r\n): GameAction => {\r\n\tconst isPlayerSireD = playerHero?.cardId?.startsWith(CardIds.SireDenathrius_BG24_HERO_100);\r\n\tconst isOpponentSireD = opponentHero?.cardId?.startsWith(CardIds.SireDenathrius_BG24_HERO_100);\r\n\tconst result: GameAction = {\r\n\t\t...action,\r\n\r\n\t\tplayerSecrets: playerHero\r\n\t\t\t? copySecrets((playerHero.secrets ?? []).filter((s) => !s.triggered))\r\n\t\t\t: undefined,\r\n\t\tplayerCardId: playerHero?.cardId,\r\n\t\tplayerEntityId: playerHero?.entityId,\r\n\r\n\t\tplayerHeroPowerCardId:\r\n\t\t\tresolveTrinketHeroPowerCardId(playerHero?.trinkets) ??\r\n\t\t\t(isPlayerSireD ? playerHero.questRewardEntities?.[0]?.cardId : null) ??\r\n\t\t\tplayerHero?.heroPowers[0]?.cardId,\r\n\t\tplayerHeroPowerEntityId: 100000002,\r\n\t\tplayerHeroPowerUsed: playerHero?.heroPowers[0]?.used,\r\n\t\tplayerHeroPowers: playerHero?.heroPowers,\r\n\r\n\t\tplayerRewardCardId:\r\n\t\t\tisPlayerSireD && playerHero?.questRewardEntities?.length < 2\r\n\t\t\t\t? null\r\n\t\t\t\t: playerHero?.questRewardEntities?.[1]?.cardId ?? playerHero?.questRewards?.[0],\r\n\t\tplayerRewardEntityId:\r\n\t\t\tisPlayerSireD && playerHero?.questRewardEntities?.length < 2\r\n\t\t\t\t? null\r\n\t\t\t\t: playerHero?.questRewardEntities?.[1]?.entityId,\r\n\t\tplayerRewardData:\r\n\t\t\tisPlayerSireD && playerHero?.questRewardEntities?.length < 2\r\n\t\t\t\t? null\r\n\t\t\t\t: playerHero?.questRewardEntities?.[0]?.scriptDataNum1 ?? 0,\r\n\t\tplayerTrinkets: playerHero?.trinkets,\r\n\r\n\t\topponentSecrets: opponentHero\r\n\t\t\t? copySecrets((opponentHero.secrets ?? []).filter((s) => !s.triggered))\r\n\t\t\t: undefined,\r\n\t\topponentCardId: opponentHero?.cardId,\r\n\t\topponentEntityId: opponentHero?.entityId,\r\n\t\topponentHeroPowerCardId:\r\n\t\t\tresolveTrinketHeroPowerCardId(opponentHero?.trinkets) ??\r\n\t\t\t(isOpponentSireD ? opponentHero.questRewardEntities?.[0]?.cardId : null) ??\r\n\t\t\topponentHero?.heroPowers[0]?.cardId ??\r\n\t\t\topponentHero?.heroPowerId,\r\n\t\topponentHeroPowerEntityId: 200000002,\r\n\t\topponentHeroPowerUsed: opponentHero?.heroPowerUsed,\r\n\t\topponentHeroPowers: opponentHero?.heroPowers,\r\n\t\topponentRewardCardId:\r\n\t\t\tisOpponentSireD && opponentHero?.questRewardEntities?.length < 2\r\n\t\t\t\t? null\r\n\t\t\t\t: opponentHero?.questRewardEntities?.[1]?.cardId ?? opponentHero?.questRewards?.[0],\r\n\t\topponentRewardEntityId:\r\n\t\t\tisOpponentSireD && opponentHero?.questRewardEntities?.length < 2\r\n\t\t\t\t? null\r\n\t\t\t\t: opponentHero?.questRewardEntities?.[1]?.entityId,\r\n\t\topponentRewardData:\r\n\t\t\tisOpponentSireD && opponentHero?.questRewardEntities?.length < 2\r\n\t\t\t\t? null\r\n\t\t\t\t: opponentHero?.questRewardEntities?.[0]?.scriptDataNum1 ?? 0,\r\n\t\topponentTrinkets: opponentHero?.trinkets,\r\n\t} as GameAction;\r\n\treturn result;\r\n};\r\n"]}
|
|
@@ -304,6 +304,8 @@ class Spectator {
|
|
|
304
304
|
deaths: this.sanitize(actions[i].deaths),
|
|
305
305
|
playerTrinkets: this.sanitizeTrinkets(actions[i].playerTrinkets),
|
|
306
306
|
opponentTrinkets: this.sanitizeTrinkets(actions[i].opponentTrinkets),
|
|
307
|
+
playerSecrets: (0, game_action_1.copySecrets)(actions[i].playerSecrets),
|
|
308
|
+
opponentSecrets: (0, game_action_1.copySecrets)(actions[i].opponentSecrets),
|
|
307
309
|
};
|
|
308
310
|
const lastAction = result.length > 0 ? result[result.length - 1] : null;
|
|
309
311
|
if (lastAction) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spectator.js","sourceRoot":"","sources":["../../../src/simulation/spectator/spectator.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsGameState } from '../../bgs-battle-info';\r\nimport { BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';\r\nimport { BoardEnchantment, BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\nimport { GameAction, buildGameAction } from './game-action';\r\nimport { GameSample } from './game-sample';\r\n\r\nconst MAX_SAMPLES = 1;\r\nconst EMPTY_ACTIONS: GameAction[] = [];\r\nconst EMPTY_SAMPLES: GameSample[] = [];\r\n\r\nexport class Spectator {\r\n\tprivate actionsForCurrentBattle: GameAction[];\r\n\tprivate wonBattles: GameSample[];\r\n\tprivate tiedBattles: GameSample[];\r\n\tprivate lostBattles: GameSample[];\r\n\t// Recording every action is a significant part of the total simulation cost, so the\r\n\t// main simulation loop runs with recording off. Outcome samples are captured post-hoc:\r\n\t// once the outcome distribution is known, a few battles are re-run with recording\r\n\t// explicitly turned on until each outcome bucket that occurred has a sample.\r\n\tprivate recording = false;\r\n\r\n\tconstructor(private readonly enabled: boolean) {\r\n\t\tif (enabled) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t\tthis.wonBattles = [];\r\n\t\t\tthis.tiedBattles = [];\r\n\t\t\tthis.lostBattles = [];\r\n\t\t} else {\r\n\t\t\tthis.actionsForCurrentBattle = EMPTY_ACTIONS;\r\n\t\t\tthis.wonBattles = EMPTY_SAMPLES;\r\n\t\t\tthis.tiedBattles = EMPTY_SAMPLES;\r\n\t\t\tthis.lostBattles = EMPTY_SAMPLES;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic startRecording(): void {\r\n\t\tif (this.enabled) {\r\n\t\t\tthis.recording = true;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic stopRecording(): void {\r\n\t\tthis.recording = false;\r\n\t\tif (this.enabled) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t}\r\n\t}\r\n\r\n\tpublic hasSampleFor(result: 'won' | 'lost' | 'tied'): boolean {\r\n\t\tswitch (result) {\r\n\t\t\tcase 'won':\r\n\t\t\t\treturn this.wonBattles.length >= MAX_SAMPLES;\r\n\t\t\tcase 'lost':\r\n\t\t\t\treturn this.lostBattles.length >= MAX_SAMPLES;\r\n\t\t\tcase 'tied':\r\n\t\t\t\treturn this.tiedBattles.length >= MAX_SAMPLES;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic prune(): void {\r\n\t\tthis.wonBattles = this.wonBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.lostBattles = this.lostBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.tiedBattles = this.tiedBattles.slice(0, MAX_SAMPLES);\r\n\t}\r\n\r\n\tpublic buildOutcomeSamples(gameState: BgsGameState): {\r\n\t\twon: readonly GameSample[];\r\n\t\tlost: readonly GameSample[];\r\n\t\ttied: readonly GameSample[];\r\n\t} {\r\n\t\tif (!this.enabled) {\r\n\t\t\treturn {\r\n\t\t\t\twon: [],\r\n\t\t\t\tlost: [],\r\n\t\t\t\ttied: [],\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn {\r\n\t\t\twon: this.wonBattles?.map((battle) => this.cleanUpActions(battle, gameState)),\r\n\t\t\tlost: this.lostBattles?.map((battle) => this.cleanUpActions(battle, gameState)),\r\n\t\t\ttied: this.tiedBattles?.map((battle) => this.cleanUpActions(battle, gameState)),\r\n\t\t};\r\n\t}\r\n\r\n\tprivate cleanUpActions(battle: GameSample, gameState: BgsGameState): GameSample {\r\n\t\tconst collapsed = this.collapseActions(battle.actions);\r\n\t\tconst result: GameSample = {\r\n\t\t\t...battle,\r\n\t\t\tactions: collapsed,\r\n\t\t\tanomalies: gameState.anomalies,\r\n\t\t};\r\n\t\treturn result;\r\n\t}\r\n\r\n\tpublic commitBattleResult(result: 'won' | 'lost' | 'tied'): void {\r\n\t\tif (!this.enabled) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!this.recording) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst actionsForBattle = this.actionsForCurrentBattle;\r\n\t\tthis.actionsForCurrentBattle = [];\r\n\r\n\t\tconst battle: GameSample = {\r\n\t\t\tactions: actionsForBattle,\r\n\t\t\tanomalies: [],\r\n\t\t};\r\n\t\t// Only keep the sample if this bucket still needs one (prune() would discard the\r\n\t\t// extras anyway, and holding on to them wastes memory)\r\n\t\tswitch (result) {\r\n\t\t\tcase 'won':\r\n\t\t\t\tif (this.wonBattles.length < MAX_SAMPLES) {\r\n\t\t\t\t\tthis.wonBattles.push(battle);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'lost':\r\n\t\t\t\tif (this.lostBattles.length < MAX_SAMPLES) {\r\n\t\t\t\t\tthis.lostBattles.push(battle);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tied':\r\n\t\t\t\tif (this.tiedBattles.length < MAX_SAMPLES) {\r\n\t\t\t\t\tthis.tiedBattles.push(battle);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic registerAttack(\r\n\t\tattackingEntity: BoardEntity,\r\n\t\tdefendingEntity: BoardEntity,\r\n\t\tattackingBoard: readonly BoardEntity[],\r\n\t\tdefendingBoard: readonly BoardEntity[],\r\n\t\tattackingBoardHero: BgsPlayerEntity,\r\n\t\tdefendingBoardHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// console.debug(\r\n\t\t// \t'\\n register attack',\r\n\t\t// \tstringifySimple(attackingBoard),\r\n\t\t// \t'\\n',\r\n\t\t// \tstringifySimple(defendingBoard),\r\n\t\t// \t'\\n',\r\n\t\t// \tattackingBoard.find((e) => e.entityId === 2441),\r\n\t\t// \t'\\n',\r\n\t\t// \tattackingBoard.find((e) => e.entityId === 2442),\r\n\t\t// );\r\n\t\tconst isAttackerFriendly = attackingBoard.every((entity) => entity.friendly);\r\n\t\tconst playerHero = isAttackerFriendly ? attackingBoardHero : defendingBoardHero;\r\n\t\tconst opponentHero = isAttackerFriendly ? defendingBoardHero : attackingBoardHero;\r\n\t\tconst friendlyBoard = isAttackerFriendly ? attackingBoard : defendingBoard;\r\n\t\tconst opponentBoard = isAttackerFriendly ? defendingBoard : attackingBoard;\r\n\t\tconst action: GameAction = buildGameAction(playerHero, opponentHero, {\r\n\t\t\ttype: 'attack',\r\n\t\t\tsourceEntityId: attackingEntity.entityId,\r\n\t\t\ttargetEntityId: defendingEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\tplayerHand: this.sanitize(playerHero.hand),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\topponentHand: this.sanitize(opponentHero.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerStartOfCombat(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tfriendlyHero: BgsPlayerEntity,\r\n\t\topponentHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(friendlyHero, opponentHero, {\r\n\t\t\ttype: 'start-of-combat',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPlayerAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'player-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerOpponentAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'opponent-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDamageDealt(\r\n\t\tdamagingEntity: BoardEntity,\r\n\t\tdamagedEntity: BoardEntity,\r\n\t\tdamageTaken: number,\r\n\t\tdamagedEntityBoard: BoardEntity[],\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!damagingEntity.entityId) {\r\n\t\t\t// console.error('missing damaging entity id', damagingEntity.cardId);\r\n\t\t}\r\n\t\tconst friendlyBoard = damagedEntityBoard.every((entity) => entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst opponentBoard = damagedEntityBoard.every((entity) => !entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'damage',\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tsourceEntityId: damagingEntity.entityId,\r\n\t\t\t\t\ttargetEntityId: damagedEntity.entityId,\r\n\t\t\t\t\tdamage: damageTaken,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPowerTarget(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret | BoardTrinket | BoardEnchantment,\r\n\t\ttargetEntity: BoardEntity | BgsPlayerEntity,\r\n\t\ttargetBoard: BoardEntity[],\r\n\t\thero1: BgsPlayerEntity,\r\n\t\thero2: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!targetEntity) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// console.log('registerPowerTarget', stringifySimpleCard(sourceEntity), stringifySimpleCard(targetEntity), new Error().stack);\r\n\t\tconst friendlyBoard = targetBoard?.every((entity) => entity.friendly) ? targetBoard : null;\r\n\t\tconst opponentBoard = targetBoard?.every((entity) => !entity.friendly) ? targetBoard : null;\r\n\t\tconst friendlyHero = hero1?.friendly ? hero1 : hero2?.friendly ? hero2 : null;\r\n\t\tconst opponentHero = hero1?.friendly ? hero2 : hero2?.friendly ? hero1 : null;\r\n\t\tconst action: GameAction = buildGameAction(friendlyHero, opponentHero, {\r\n\t\t\ttype: 'power-target',\r\n\t\t\tsourceEntityId:\r\n\t\t\t\t(sourceEntity as BoardEnchantment)?.originEntityId ?? (sourceEntity as BoardEntity).entityId,\r\n\t\t\ttargetEntityId: targetEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero?.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero?.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPowerTargets(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret | BoardTrinket,\r\n\t\ttargetEntities: (BoardEntity | BgsPlayerEntity)[],\r\n\t\ttargetBoard: BoardEntity[],\r\n\t\thero1: BgsPlayerEntity,\r\n\t\thero2: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!targetEntities?.length) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// console.log('registerPowerTarget', stringifySimpleCard(sourceEntity), stringifySimpleCard(targetEntity), new Error().stack);\r\n\t\tconst friendlyBoard = targetBoard?.every((entity) => entity.friendly) ? targetBoard : null;\r\n\t\tconst opponentBoard = targetBoard?.every((entity) => !entity.friendly) ? targetBoard : null;\r\n\t\tconst friendlyHero = hero1?.friendly ? hero1 : hero2?.friendly ? hero2 : null;\r\n\t\tconst opponentHero = hero1?.friendly ? hero2 : hero2?.friendly ? hero1 : null;\r\n\t\tconst action: GameAction = buildGameAction(friendlyHero, opponentHero, {\r\n\t\t\ttype: 'power-target',\r\n\t\t\tsourceEntityId: sourceEntity.entityId,\r\n\t\t\ttargetEntityIds: targetEntities.map((entity) => entity.entityId),\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero?.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero?.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerMinionsSpawn(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardTrinket,\r\n\t\tboardOnWhichToSpawn: BoardEntity[],\r\n\t\tspawnedEntities: readonly BoardEntity[],\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!spawnedEntities || spawnedEntities.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!sourceEntity?.entityId) {\r\n\t\t\t// console.error('missing spawn source entity id', sourceEntity);\r\n\t\t}\r\n\t\tconst friendlyBoard = boardOnWhichToSpawn.every((entity) => entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst opponentBoard = boardOnWhichToSpawn.every((entity) => !entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'spawn',\r\n\t\t\tspawns: this.sanitize(spawnedEntities),\r\n\t\t\tsourceEntityId: sourceEntity?.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDeadEntities(\r\n\t\tdeadMinionIndexes1: number[],\r\n\t\tdeadEntities1: BoardEntity[],\r\n\t\tboard1: BoardEntity[],\r\n\t\tdeadMinionIndexes2: number[],\r\n\t\tdeadEntities2: BoardEntity[],\r\n\t\tboard2: BoardEntity[],\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst deaths = [...(deadEntities1 || []), ...(deadEntities2 || [])];\r\n\t\tif (!deaths || deaths.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'minion-death',\r\n\t\t\tdeaths: this.sanitize(deaths),\r\n\t\t\tdeadMinionsPositionsOnBoard: [\r\n\t\t\t\t...(deadMinionIndexes1 || []).map((i) => board1.length - i),\r\n\t\t\t\t...(deadMinionIndexes2 || []).map((i) => board2.length - i),\r\n\t\t\t],\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tprivate addAction(action: GameAction) {\r\n\t\tthis.actionsForCurrentBattle.push(action);\r\n\t}\r\n\r\n\tprivate collapseActions(actions: readonly GameAction[]): readonly GameAction[] {\r\n\t\tif (!this.enabled) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\t\tif (!actions || actions.length === 0) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\t\tconst result: GameAction[] = [];\r\n\t\tfor (let i = 0; i < actions.length; i++) {\r\n\t\t\tconst action: GameAction = {\r\n\t\t\t\t...actions[i],\r\n\t\t\t\tplayerBoard: this.sanitize(actions[i].playerBoard),\r\n\t\t\t\topponentBoard: this.sanitize(actions[i].opponentBoard),\r\n\t\t\t\tplayerHand: this.sanitize(actions[i].playerHand),\r\n\t\t\t\topponentHand: this.sanitize(actions[i].opponentHand),\r\n\t\t\t\t// spawns: this.sanitize(actions[i].spawns),\r\n\t\t\t\tdeaths: this.sanitize(actions[i].deaths),\r\n\t\t\t\tplayerTrinkets: this.sanitizeTrinkets(actions[i].playerTrinkets),\r\n\t\t\t\topponentTrinkets: this.sanitizeTrinkets(actions[i].opponentTrinkets),\r\n\t\t\t};\r\n\t\t\t// action.playerBoard && console.debug('\\naction playerboard', stringifySimple(action.playerBoard));\r\n\t\t\tconst lastAction = result.length > 0 ? result[result.length - 1] : null;\r\n\r\n\t\t\tif (lastAction) {\r\n\t\t\t\taction.playerBoard = action.playerBoard ?? lastAction.playerBoard;\r\n\t\t\t\taction.opponentBoard = action.opponentBoard ?? lastAction.opponentBoard;\r\n\t\t\t\taction.playerHand = action.playerHand ?? lastAction.playerHand;\r\n\t\t\t\taction.opponentHand = action.opponentHand ?? lastAction.opponentHand;\r\n\t\t\t\taction.playerSecrets = action.playerSecrets ?? lastAction.playerSecrets;\r\n\t\t\t\taction.opponentSecrets = action.opponentSecrets ?? lastAction.opponentSecrets;\r\n\t\t\t\taction.playerRewardCardId = action.playerRewardCardId ?? lastAction.playerRewardCardId;\r\n\t\t\t\taction.playerRewardEntityId = action.playerRewardEntityId ?? lastAction.playerRewardEntityId;\r\n\t\t\t\taction.playerRewardData = action.playerRewardData ?? lastAction.playerRewardData;\r\n\t\t\t\taction.opponentRewardCardId = action.opponentRewardCardId ?? lastAction.opponentRewardCardId;\r\n\t\t\t\taction.opponentRewardEntityId = action.opponentRewardEntityId ?? lastAction.opponentRewardEntityId;\r\n\t\t\t\taction.opponentRewardData = action.opponentRewardData ?? lastAction.opponentRewardData;\r\n\t\t\t\taction.playerCardId = action.playerCardId ?? lastAction.playerCardId;\r\n\t\t\t\taction.playerEntityId = action.playerEntityId ?? lastAction.playerEntityId;\r\n\t\t\t\taction.playerHeroPowerCardId = action.playerHeroPowerCardId ?? lastAction.playerHeroPowerCardId;\r\n\t\t\t\taction.playerHeroPowerEntityId = action.playerHeroPowerEntityId ?? lastAction.playerHeroPowerEntityId;\r\n\t\t\t\taction.playerHeroPowerUsed = action.playerHeroPowerUsed ?? lastAction.playerHeroPowerUsed;\r\n\t\t\t\taction.opponentCardId = action.opponentCardId ?? lastAction.opponentCardId;\r\n\t\t\t\taction.opponentEntityId = action.opponentEntityId ?? lastAction.opponentEntityId;\r\n\t\t\t\taction.opponentHeroPowerCardId = action.opponentHeroPowerCardId ?? lastAction.opponentHeroPowerCardId;\r\n\t\t\t\taction.opponentHeroPowerEntityId =\r\n\t\t\t\t\taction.opponentHeroPowerEntityId ?? lastAction.opponentHeroPowerEntityId;\r\n\t\t\t\taction.opponentHeroPowerUsed = action.opponentHeroPowerUsed ?? lastAction.opponentHeroPowerUsed;\r\n\t\t\t\taction.playerTrinkets = action.playerTrinkets ?? lastAction.playerTrinkets;\r\n\t\t\t\taction.opponentTrinkets = action.opponentTrinkets ?? lastAction.opponentTrinkets;\r\n\t\t\t}\r\n\r\n\t\t\tif (lastAction && action.type === 'damage' && lastAction.type === 'attack') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t\tlastAction.playerTrinkets = action.playerTrinkets;\r\n\t\t\t\tlastAction.opponentTrinkets = action.opponentTrinkets;\r\n\t\t\t} else if (lastAction && action.type === 'damage' && lastAction.type === 'damage') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t\tlastAction.playerTrinkets = action.playerTrinkets;\r\n\t\t\t\tlastAction.opponentTrinkets = action.opponentTrinkets;\r\n\t\t\t} else if (\r\n\t\t\t\tlastAction &&\r\n\t\t\t\taction.type === 'power-target' &&\r\n\t\t\t\tlastAction.type === 'power-target' &&\r\n\t\t\t\taction.sourceEntityId === lastAction.sourceEntityId\r\n\t\t\t) {\r\n\t\t\t\tlastAction.targetEntityIds =\r\n\t\t\t\t\tlastAction.targetEntityIds ?? (lastAction.targetEntityId ? [lastAction.targetEntityId] : []);\r\n\t\t\t\taction.targetEntityIds =\r\n\t\t\t\t\taction.targetEntityIds ?? (action.targetEntityId ? [action.targetEntityId] : []);\r\n\t\t\t\tlastAction.targetEntityIds.push(...action.targetEntityIds);\r\n\t\t\t\t// So that when multiple Leapfroggers enchantments target the same minion,\r\n\t\t\t\t// we can count them in the replay viewer's text\r\n\t\t\t\t// lastAction.targetEntityIds = [...new Set(lastAction.targetEntityIds)];\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t\tlastAction.playerTrinkets = action.playerTrinkets;\r\n\t\t\t\tlastAction.opponentTrinkets = action.opponentTrinkets;\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(action);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\n\t// Calling sanitize every time before we add an action to the list is mandatory, since\r\n\t// the entities and boards are mutable\r\n\tprivate sanitize(board: readonly BoardEntity[]): readonly BoardEntity[] {\r\n\t\tif (!board) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\treturn board.map(\r\n\t\t\t(entity) =>\r\n\t\t\t\t({\r\n\t\t\t\t\tentityId: entity.entityId,\r\n\t\t\t\t\tcardId: entity.cardId,\r\n\t\t\t\t\tfriendly: entity.friendly,\r\n\t\t\t\t\tattack: entity.attack,\r\n\t\t\t\t\thealth: entity.health,\r\n\t\t\t\t\tmaxHealth: entity.maxHealth,\r\n\t\t\t\t\ttaunt: entity.taunt,\r\n\t\t\t\t\tdivineShield: entity.divineShield,\r\n\t\t\t\t\tpoisonous: entity.poisonous,\r\n\t\t\t\t\tvenomous: entity.venomous,\r\n\t\t\t\t\treborn: entity.reborn,\r\n\t\t\t\t\twindfury: entity.windfury,\r\n\t\t\t\t\tstealth: entity.stealth,\r\n\t\t\t\t} as BoardEntity),\r\n\t\t);\r\n\t}\r\n\r\n\tprivate sanitizeTrinkets(trinkets: readonly BoardTrinket[]): readonly BoardTrinket[] {\r\n\t\tif (!trinkets?.length) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\tconst result = trinkets.map(\r\n\t\t\t(t) =>\r\n\t\t\t\t({\r\n\t\t\t\t\tcardId: t.cardId,\r\n\t\t\t\t\tentityId: t.entityId,\r\n\t\t\t\t\tscriptDataNum1: t.scriptDataNum1,\r\n\t\t\t\t\tscriptDataNum6: t.scriptDataNum6,\r\n\t\t\t\t\ttags: t.tags,\r\n\t\t\t\t} as BoardTrinket),\r\n\t\t);\r\n\t\treturn result;\r\n\t}\r\n}\r\n\r\n/** Shared no-op spectator for single-combat / tavern triggers (no sample arrays). */\r\nexport const noopSpectator = new Spectator(false);\r\n\r\n"]}
|
|
1
|
+
{"version":3,"file":"spectator.js","sourceRoot":"","sources":["../../../src/simulation/spectator/spectator.ts"],"names":[],"mappings":"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","sourcesContent":["import { BgsGameState } from '../../bgs-battle-info';\r\nimport { BgsPlayerEntity, BoardTrinket } from '../../bgs-player-entity';\r\nimport { BoardEnchantment, BoardEntity } from '../../board-entity';\r\nimport { BoardSecret } from '../../board-secret';\r\nimport { GameAction, buildGameAction, copySecrets } from './game-action';\r\nimport { GameSample } from './game-sample';\r\n\r\nconst MAX_SAMPLES = 1;\r\nconst EMPTY_ACTIONS: GameAction[] = [];\r\nconst EMPTY_SAMPLES: GameSample[] = [];\r\n\r\nexport class Spectator {\r\n\tprivate actionsForCurrentBattle: GameAction[];\r\n\tprivate wonBattles: GameSample[];\r\n\tprivate tiedBattles: GameSample[];\r\n\tprivate lostBattles: GameSample[];\r\n\t// Recording every action is a significant part of the total simulation cost, so the\r\n\t// main simulation loop runs with recording off. Outcome samples are captured post-hoc:\r\n\t// once the outcome distribution is known, a few battles are re-run with recording\r\n\t// explicitly turned on until each outcome bucket that occurred has a sample.\r\n\tprivate recording = false;\r\n\r\n\tconstructor(private readonly enabled: boolean) {\r\n\t\tif (enabled) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t\tthis.wonBattles = [];\r\n\t\t\tthis.tiedBattles = [];\r\n\t\t\tthis.lostBattles = [];\r\n\t\t} else {\r\n\t\t\tthis.actionsForCurrentBattle = EMPTY_ACTIONS;\r\n\t\t\tthis.wonBattles = EMPTY_SAMPLES;\r\n\t\t\tthis.tiedBattles = EMPTY_SAMPLES;\r\n\t\t\tthis.lostBattles = EMPTY_SAMPLES;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic startRecording(): void {\r\n\t\tif (this.enabled) {\r\n\t\t\tthis.recording = true;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic stopRecording(): void {\r\n\t\tthis.recording = false;\r\n\t\tif (this.enabled) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t}\r\n\t}\r\n\r\n\tpublic hasSampleFor(result: 'won' | 'lost' | 'tied'): boolean {\r\n\t\tswitch (result) {\r\n\t\t\tcase 'won':\r\n\t\t\t\treturn this.wonBattles.length >= MAX_SAMPLES;\r\n\t\t\tcase 'lost':\r\n\t\t\t\treturn this.lostBattles.length >= MAX_SAMPLES;\r\n\t\t\tcase 'tied':\r\n\t\t\t\treturn this.tiedBattles.length >= MAX_SAMPLES;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic prune(): void {\r\n\t\tthis.wonBattles = this.wonBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.lostBattles = this.lostBattles.slice(0, MAX_SAMPLES);\r\n\t\tthis.tiedBattles = this.tiedBattles.slice(0, MAX_SAMPLES);\r\n\t}\r\n\r\n\tpublic buildOutcomeSamples(gameState: BgsGameState): {\r\n\t\twon: readonly GameSample[];\r\n\t\tlost: readonly GameSample[];\r\n\t\ttied: readonly GameSample[];\r\n\t} {\r\n\t\tif (!this.enabled) {\r\n\t\t\treturn {\r\n\t\t\t\twon: [],\r\n\t\t\t\tlost: [],\r\n\t\t\t\ttied: [],\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn {\r\n\t\t\twon: this.wonBattles?.map((battle) => this.cleanUpActions(battle, gameState)),\r\n\t\t\tlost: this.lostBattles?.map((battle) => this.cleanUpActions(battle, gameState)),\r\n\t\t\ttied: this.tiedBattles?.map((battle) => this.cleanUpActions(battle, gameState)),\r\n\t\t};\r\n\t}\r\n\r\n\tprivate cleanUpActions(battle: GameSample, gameState: BgsGameState): GameSample {\r\n\t\tconst collapsed = this.collapseActions(battle.actions);\r\n\t\tconst result: GameSample = {\r\n\t\t\t...battle,\r\n\t\t\tactions: collapsed,\r\n\t\t\tanomalies: gameState.anomalies,\r\n\t\t};\r\n\t\treturn result;\r\n\t}\r\n\r\n\tpublic commitBattleResult(result: 'won' | 'lost' | 'tied'): void {\r\n\t\tif (!this.enabled) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!this.recording) {\r\n\t\t\tthis.actionsForCurrentBattle = [];\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst actionsForBattle = this.actionsForCurrentBattle;\r\n\t\tthis.actionsForCurrentBattle = [];\r\n\r\n\t\tconst battle: GameSample = {\r\n\t\t\tactions: actionsForBattle,\r\n\t\t\tanomalies: [],\r\n\t\t};\r\n\t\t// Only keep the sample if this bucket still needs one (prune() would discard the\r\n\t\t// extras anyway, and holding on to them wastes memory)\r\n\t\tswitch (result) {\r\n\t\t\tcase 'won':\r\n\t\t\t\tif (this.wonBattles.length < MAX_SAMPLES) {\r\n\t\t\t\t\tthis.wonBattles.push(battle);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'lost':\r\n\t\t\t\tif (this.lostBattles.length < MAX_SAMPLES) {\r\n\t\t\t\t\tthis.lostBattles.push(battle);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tied':\r\n\t\t\t\tif (this.tiedBattles.length < MAX_SAMPLES) {\r\n\t\t\t\t\tthis.tiedBattles.push(battle);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic registerAttack(\r\n\t\tattackingEntity: BoardEntity,\r\n\t\tdefendingEntity: BoardEntity,\r\n\t\tattackingBoard: readonly BoardEntity[],\r\n\t\tdefendingBoard: readonly BoardEntity[],\r\n\t\tattackingBoardHero: BgsPlayerEntity,\r\n\t\tdefendingBoardHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// console.debug(\r\n\t\t// \t'\\n register attack',\r\n\t\t// \tstringifySimple(attackingBoard),\r\n\t\t// \t'\\n',\r\n\t\t// \tstringifySimple(defendingBoard),\r\n\t\t// \t'\\n',\r\n\t\t// \tattackingBoard.find((e) => e.entityId === 2441),\r\n\t\t// \t'\\n',\r\n\t\t// \tattackingBoard.find((e) => e.entityId === 2442),\r\n\t\t// );\r\n\t\tconst isAttackerFriendly = attackingBoard.every((entity) => entity.friendly);\r\n\t\tconst playerHero = isAttackerFriendly ? attackingBoardHero : defendingBoardHero;\r\n\t\tconst opponentHero = isAttackerFriendly ? defendingBoardHero : attackingBoardHero;\r\n\t\tconst friendlyBoard = isAttackerFriendly ? attackingBoard : defendingBoard;\r\n\t\tconst opponentBoard = isAttackerFriendly ? defendingBoard : attackingBoard;\r\n\t\tconst action: GameAction = buildGameAction(playerHero, opponentHero, {\r\n\t\t\ttype: 'attack',\r\n\t\t\tsourceEntityId: attackingEntity.entityId,\r\n\t\t\ttargetEntityId: defendingEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\tplayerHand: this.sanitize(playerHero.hand),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\topponentHand: this.sanitize(opponentHero.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerStartOfCombat(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tfriendlyHero: BgsPlayerEntity,\r\n\t\topponentHero: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(friendlyHero, opponentHero, {\r\n\t\t\ttype: 'start-of-combat',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPlayerAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'player-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerOpponentAttack(\r\n\t\tfriendlyBoard: readonly BoardEntity[],\r\n\t\topponentBoard: readonly BoardEntity[],\r\n\t\tdamage: number,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'opponent-attack',\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tdamage: damage,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDamageDealt(\r\n\t\tdamagingEntity: BoardEntity,\r\n\t\tdamagedEntity: BoardEntity,\r\n\t\tdamageTaken: number,\r\n\t\tdamagedEntityBoard: BoardEntity[],\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!damagingEntity.entityId) {\r\n\t\t\t// console.error('missing damaging entity id', damagingEntity.cardId);\r\n\t\t}\r\n\t\tconst friendlyBoard = damagedEntityBoard.every((entity) => entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst opponentBoard = damagedEntityBoard.every((entity) => !entity.friendly) ? damagedEntityBoard : null;\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'damage',\r\n\t\t\tdamages: [\r\n\t\t\t\t{\r\n\t\t\t\t\tsourceEntityId: damagingEntity.entityId,\r\n\t\t\t\t\ttargetEntityId: damagedEntity.entityId,\r\n\t\t\t\t\tdamage: damageTaken,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPowerTarget(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret | BoardTrinket | BoardEnchantment,\r\n\t\ttargetEntity: BoardEntity | BgsPlayerEntity,\r\n\t\ttargetBoard: BoardEntity[],\r\n\t\thero1: BgsPlayerEntity,\r\n\t\thero2: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!targetEntity) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// console.log('registerPowerTarget', stringifySimpleCard(sourceEntity), stringifySimpleCard(targetEntity), new Error().stack);\r\n\t\tconst friendlyBoard = targetBoard?.every((entity) => entity.friendly) ? targetBoard : null;\r\n\t\tconst opponentBoard = targetBoard?.every((entity) => !entity.friendly) ? targetBoard : null;\r\n\t\tconst friendlyHero = hero1?.friendly ? hero1 : hero2?.friendly ? hero2 : null;\r\n\t\tconst opponentHero = hero1?.friendly ? hero2 : hero2?.friendly ? hero1 : null;\r\n\t\tconst action: GameAction = buildGameAction(friendlyHero, opponentHero, {\r\n\t\t\ttype: 'power-target',\r\n\t\t\tsourceEntityId:\r\n\t\t\t\t(sourceEntity as BoardEnchantment)?.originEntityId ?? (sourceEntity as BoardEntity).entityId,\r\n\t\t\ttargetEntityId: targetEntity.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero?.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero?.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerPowerTargets(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardSecret | BoardTrinket,\r\n\t\ttargetEntities: (BoardEntity | BgsPlayerEntity)[],\r\n\t\ttargetBoard: BoardEntity[],\r\n\t\thero1: BgsPlayerEntity,\r\n\t\thero2: BgsPlayerEntity,\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!targetEntities?.length) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t// console.log('registerPowerTarget', stringifySimpleCard(sourceEntity), stringifySimpleCard(targetEntity), new Error().stack);\r\n\t\tconst friendlyBoard = targetBoard?.every((entity) => entity.friendly) ? targetBoard : null;\r\n\t\tconst opponentBoard = targetBoard?.every((entity) => !entity.friendly) ? targetBoard : null;\r\n\t\tconst friendlyHero = hero1?.friendly ? hero1 : hero2?.friendly ? hero2 : null;\r\n\t\tconst opponentHero = hero1?.friendly ? hero2 : hero2?.friendly ? hero1 : null;\r\n\t\tconst action: GameAction = buildGameAction(friendlyHero, opponentHero, {\r\n\t\t\ttype: 'power-target',\r\n\t\t\tsourceEntityId: sourceEntity.entityId,\r\n\t\t\ttargetEntityIds: targetEntities.map((entity) => entity.entityId),\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: this.sanitize(friendlyHero?.hand),\r\n\t\t\topponentHand: this.sanitize(opponentHero?.hand),\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerMinionsSpawn(\r\n\t\tsourceEntity: BoardEntity | BgsPlayerEntity | BoardTrinket,\r\n\t\tboardOnWhichToSpawn: BoardEntity[],\r\n\t\tspawnedEntities: readonly BoardEntity[],\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!spawnedEntities || spawnedEntities.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!sourceEntity?.entityId) {\r\n\t\t\t// console.error('missing spawn source entity id', sourceEntity);\r\n\t\t}\r\n\t\tconst friendlyBoard = boardOnWhichToSpawn.every((entity) => entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst opponentBoard = boardOnWhichToSpawn.every((entity) => !entity.friendly) ? boardOnWhichToSpawn : null;\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'spawn',\r\n\t\t\tspawns: this.sanitize(spawnedEntities),\r\n\t\t\tsourceEntityId: sourceEntity?.entityId,\r\n\t\t\tplayerBoard: this.sanitize(friendlyBoard),\r\n\t\t\topponentBoard: this.sanitize(opponentBoard),\r\n\t\t\tplayerHand: null,\r\n\t\t\topponentHand: null,\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tpublic registerDeadEntities(\r\n\t\tdeadMinionIndexes1: number[],\r\n\t\tdeadEntities1: BoardEntity[],\r\n\t\tboard1: BoardEntity[],\r\n\t\tdeadMinionIndexes2: number[],\r\n\t\tdeadEntities2: BoardEntity[],\r\n\t\tboard2: BoardEntity[],\r\n\t): void {\r\n\t\tif (!this.recording) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst deaths = [...(deadEntities1 || []), ...(deadEntities2 || [])];\r\n\t\tif (!deaths || deaths.length === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst action: GameAction = buildGameAction(null, null, {\r\n\t\t\ttype: 'minion-death',\r\n\t\t\tdeaths: this.sanitize(deaths),\r\n\t\t\tdeadMinionsPositionsOnBoard: [\r\n\t\t\t\t...(deadMinionIndexes1 || []).map((i) => board1.length - i),\r\n\t\t\t\t...(deadMinionIndexes2 || []).map((i) => board2.length - i),\r\n\t\t\t],\r\n\t\t});\r\n\t\tthis.addAction(action);\r\n\t}\r\n\r\n\tprivate addAction(action: GameAction) {\r\n\t\tthis.actionsForCurrentBattle.push(action);\r\n\t}\r\n\r\n\tprivate collapseActions(actions: readonly GameAction[]): readonly GameAction[] {\r\n\t\tif (!this.enabled) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\t\tif (!actions || actions.length === 0) {\r\n\t\t\treturn [];\r\n\t\t}\r\n\t\tconst result: GameAction[] = [];\r\n\t\tfor (let i = 0; i < actions.length; i++) {\r\n\t\t\tconst action: GameAction = {\r\n\t\t\t\t...actions[i],\r\n\t\t\t\tplayerBoard: this.sanitize(actions[i].playerBoard),\r\n\t\t\t\topponentBoard: this.sanitize(actions[i].opponentBoard),\r\n\t\t\t\tplayerHand: this.sanitize(actions[i].playerHand),\r\n\t\t\t\topponentHand: this.sanitize(actions[i].opponentHand),\r\n\t\t\t\t// spawns: this.sanitize(actions[i].spawns),\r\n\t\t\t\tdeaths: this.sanitize(actions[i].deaths),\r\n\t\t\t\tplayerTrinkets: this.sanitizeTrinkets(actions[i].playerTrinkets),\r\n\t\t\t\topponentTrinkets: this.sanitizeTrinkets(actions[i].opponentTrinkets),\r\n\t\t\t\tplayerSecrets: copySecrets(actions[i].playerSecrets),\r\n\t\t\t\topponentSecrets: copySecrets(actions[i].opponentSecrets),\r\n\t\t\t};\r\n\t\t\t// action.playerBoard && console.debug('\\naction playerboard', stringifySimple(action.playerBoard));\r\n\t\t\tconst lastAction = result.length > 0 ? result[result.length - 1] : null;\r\n\r\n\t\t\tif (lastAction) {\r\n\t\t\t\taction.playerBoard = action.playerBoard ?? lastAction.playerBoard;\r\n\t\t\t\taction.opponentBoard = action.opponentBoard ?? lastAction.opponentBoard;\r\n\t\t\t\taction.playerHand = action.playerHand ?? lastAction.playerHand;\r\n\t\t\t\taction.opponentHand = action.opponentHand ?? lastAction.opponentHand;\r\n\t\t\t\taction.playerSecrets = action.playerSecrets ?? lastAction.playerSecrets;\r\n\t\t\t\taction.opponentSecrets = action.opponentSecrets ?? lastAction.opponentSecrets;\r\n\t\t\t\taction.playerRewardCardId = action.playerRewardCardId ?? lastAction.playerRewardCardId;\r\n\t\t\t\taction.playerRewardEntityId = action.playerRewardEntityId ?? lastAction.playerRewardEntityId;\r\n\t\t\t\taction.playerRewardData = action.playerRewardData ?? lastAction.playerRewardData;\r\n\t\t\t\taction.opponentRewardCardId = action.opponentRewardCardId ?? lastAction.opponentRewardCardId;\r\n\t\t\t\taction.opponentRewardEntityId = action.opponentRewardEntityId ?? lastAction.opponentRewardEntityId;\r\n\t\t\t\taction.opponentRewardData = action.opponentRewardData ?? lastAction.opponentRewardData;\r\n\t\t\t\taction.playerCardId = action.playerCardId ?? lastAction.playerCardId;\r\n\t\t\t\taction.playerEntityId = action.playerEntityId ?? lastAction.playerEntityId;\r\n\t\t\t\taction.playerHeroPowerCardId = action.playerHeroPowerCardId ?? lastAction.playerHeroPowerCardId;\r\n\t\t\t\taction.playerHeroPowerEntityId = action.playerHeroPowerEntityId ?? lastAction.playerHeroPowerEntityId;\r\n\t\t\t\taction.playerHeroPowerUsed = action.playerHeroPowerUsed ?? lastAction.playerHeroPowerUsed;\r\n\t\t\t\taction.opponentCardId = action.opponentCardId ?? lastAction.opponentCardId;\r\n\t\t\t\taction.opponentEntityId = action.opponentEntityId ?? lastAction.opponentEntityId;\r\n\t\t\t\taction.opponentHeroPowerCardId = action.opponentHeroPowerCardId ?? lastAction.opponentHeroPowerCardId;\r\n\t\t\t\taction.opponentHeroPowerEntityId =\r\n\t\t\t\t\taction.opponentHeroPowerEntityId ?? lastAction.opponentHeroPowerEntityId;\r\n\t\t\t\taction.opponentHeroPowerUsed = action.opponentHeroPowerUsed ?? lastAction.opponentHeroPowerUsed;\r\n\t\t\t\taction.playerTrinkets = action.playerTrinkets ?? lastAction.playerTrinkets;\r\n\t\t\t\taction.opponentTrinkets = action.opponentTrinkets ?? lastAction.opponentTrinkets;\r\n\t\t\t}\r\n\r\n\t\t\tif (lastAction && action.type === 'damage' && lastAction.type === 'attack') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t\tlastAction.playerTrinkets = action.playerTrinkets;\r\n\t\t\t\tlastAction.opponentTrinkets = action.opponentTrinkets;\r\n\t\t\t} else if (lastAction && action.type === 'damage' && lastAction.type === 'damage') {\r\n\t\t\t\tlastAction.damages = lastAction.damages || [];\r\n\t\t\t\tlastAction.damages.push({\r\n\t\t\t\t\tdamage: action.damages[0].damage,\r\n\t\t\t\t\tsourceEntityId: action.damages[0].sourceEntityId,\r\n\t\t\t\t\ttargetEntityId: action.damages[0].targetEntityId,\r\n\t\t\t\t});\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t\tlastAction.playerTrinkets = action.playerTrinkets;\r\n\t\t\t\tlastAction.opponentTrinkets = action.opponentTrinkets;\r\n\t\t\t} else if (\r\n\t\t\t\tlastAction &&\r\n\t\t\t\taction.type === 'power-target' &&\r\n\t\t\t\tlastAction.type === 'power-target' &&\r\n\t\t\t\taction.sourceEntityId === lastAction.sourceEntityId\r\n\t\t\t) {\r\n\t\t\t\tlastAction.targetEntityIds =\r\n\t\t\t\t\tlastAction.targetEntityIds ?? (lastAction.targetEntityId ? [lastAction.targetEntityId] : []);\r\n\t\t\t\taction.targetEntityIds =\r\n\t\t\t\t\taction.targetEntityIds ?? (action.targetEntityId ? [action.targetEntityId] : []);\r\n\t\t\t\tlastAction.targetEntityIds.push(...action.targetEntityIds);\r\n\t\t\t\t// So that when multiple Leapfroggers enchantments target the same minion,\r\n\t\t\t\t// we can count them in the replay viewer's text\r\n\t\t\t\t// lastAction.targetEntityIds = [...new Set(lastAction.targetEntityIds)];\r\n\t\t\t\tlastAction.playerBoard = action.playerBoard;\r\n\t\t\t\tlastAction.opponentBoard = action.opponentBoard;\r\n\t\t\t\tlastAction.playerHand = action.playerHand;\r\n\t\t\t\tlastAction.opponentHand = action.opponentHand;\r\n\t\t\t\tlastAction.playerSecrets = action.playerSecrets;\r\n\t\t\t\tlastAction.opponentSecrets = action.opponentSecrets;\r\n\t\t\t\tlastAction.playerTrinkets = action.playerTrinkets;\r\n\t\t\t\tlastAction.opponentTrinkets = action.opponentTrinkets;\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(action);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn result;\r\n\t}\r\n\r\n\t// Calling sanitize every time before we add an action to the list is mandatory, since\r\n\t// the entities and boards are mutable\r\n\tprivate sanitize(board: readonly BoardEntity[]): readonly BoardEntity[] {\r\n\t\tif (!board) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\treturn board.map(\r\n\t\t\t(entity) =>\r\n\t\t\t\t({\r\n\t\t\t\t\tentityId: entity.entityId,\r\n\t\t\t\t\tcardId: entity.cardId,\r\n\t\t\t\t\tfriendly: entity.friendly,\r\n\t\t\t\t\tattack: entity.attack,\r\n\t\t\t\t\thealth: entity.health,\r\n\t\t\t\t\tmaxHealth: entity.maxHealth,\r\n\t\t\t\t\ttaunt: entity.taunt,\r\n\t\t\t\t\tdivineShield: entity.divineShield,\r\n\t\t\t\t\tpoisonous: entity.poisonous,\r\n\t\t\t\t\tvenomous: entity.venomous,\r\n\t\t\t\t\treborn: entity.reborn,\r\n\t\t\t\t\twindfury: entity.windfury,\r\n\t\t\t\t\tstealth: entity.stealth,\r\n\t\t\t\t} as BoardEntity),\r\n\t\t);\r\n\t}\r\n\r\n\tprivate sanitizeTrinkets(trinkets: readonly BoardTrinket[]): readonly BoardTrinket[] {\r\n\t\tif (!trinkets?.length) {\r\n\t\t\treturn undefined;\r\n\t\t}\r\n\t\tconst result = trinkets.map(\r\n\t\t\t(t) =>\r\n\t\t\t\t({\r\n\t\t\t\t\tcardId: t.cardId,\r\n\t\t\t\t\tentityId: t.entityId,\r\n\t\t\t\t\tscriptDataNum1: t.scriptDataNum1,\r\n\t\t\t\t\tscriptDataNum6: t.scriptDataNum6,\r\n\t\t\t\t\ttags: t.tags,\r\n\t\t\t\t} as BoardTrinket),\r\n\t\t);\r\n\t\treturn result;\r\n\t}\r\n}\r\n\r\n/** Shared no-op spectator for single-combat / tavern triggers (no sample arrays). */\r\nexport const noopSpectator = new Spectator(false);\r\n\r\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleStartOfCombat = void 0;
|
|
4
|
+
const deity_1 = require("../deity");
|
|
4
5
|
const pending_effects_1 = require("../pending-effects");
|
|
5
6
|
const stats_1 = require("../stats");
|
|
6
7
|
const soc_anomalies_1 = require("./soc-anomalies");
|
|
@@ -12,6 +13,8 @@ const soc_quest_reward_1 = require("./soc-quest-reward");
|
|
|
12
13
|
const soc_secret_1 = require("./soc-secret");
|
|
13
14
|
const soc_trinket_1 = require("./soc-trinket");
|
|
14
15
|
const handleStartOfCombat = (playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState) => {
|
|
16
|
+
(0, deity_1.stampOnBoardDeityAuras)(playerBoard, playerEntity, gameState.allCards);
|
|
17
|
+
(0, deity_1.stampOnBoardDeityAuras)(opponentBoard, opponentEntity, gameState.allCards);
|
|
15
18
|
const shouldRecomputeCurrentAttacker = true;
|
|
16
19
|
if (shouldRecomputeCurrentAttacker) {
|
|
17
20
|
currentAttacker =
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-of-combat.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/start-of-combat.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { BgsPlayerEntity } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { FullGameState } from '../internal-game-state';\r\nimport { resolvePendingEffects } from '../pending-effects';\r\nimport { applyAfterStatsUpdate } from '../stats';\r\nimport { StartOfCombatPhase } from './phases';\r\nimport { handleStartOfCombatAnomalies } from './soc-anomalies';\r\nimport { handleStartOfCombatHeroPowers } from './soc-hero-power';\r\nimport { handleIllidanHeroPowers } from './soc-illidan-hero-power';\r\nimport { handleStartOfCombatMinions } from './soc-minion';\r\nimport { handlePreCombatHeroPowers } from './soc-pre-combat-hero-power';\r\nimport { handleStartOfCombatQuestRewards } from './soc-quest-reward';\r\nimport { handleStartOfCombatSecrets } from './soc-secret';\r\nimport { handleStartOfCombatTrinkets } from './soc-trinket';\r\n\r\n// TODO 20/04/2024: I'm not too sure about some ordering. The way I understand it, the Start of Combat has\r\n// multiple phases, and in each phase the player order is random\r\n// However, looking at http://replays.firestoneapp.com/?reviewId=a577602e-06f3-4c4b-928d-36ea98c2e6d5&turn=5&action=0,\r\n// it feels that a \"start of combat\" minion effect could trigger before an opponent's hero power effect\r\n// Or is that limited to Bru'kan?\r\n// I feel that I've asked a lot of questions recently, so I don't want to add that one to the list, as the interaction\r\n// is for now pretty marginal\r\nexport const handleStartOfCombat = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\tconst shouldRecomputeCurrentAttacker = true;\r\n\tif (shouldRecomputeCurrentAttacker) {\r\n\t\tcurrentAttacker =\r\n\t\t\tplayerBoard.length > opponentBoard.length\r\n\t\t\t\t? 0\r\n\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t? 1\r\n\t\t\t\t: Math.round(Math.random());\r\n\t}\r\n\r\n\t// UPDATE 2024-10-10: changed in 30.6, according to a message from Mitchell on Discord\r\n\t// UPDATE 2026-02-21:\r\n\t// K I double checked in-game and documentation and this is the trigger order:\r\n\t// Trinket/Quest Reward\r\n\t// Pre-combat hero powers (e.g. Lich King)\r\n\t// Combat First hero powers (e.g. Illidan)\r\n\t// Start of combat hero powers (e.g. Basically all other hero powers)\r\n\t// Spells (e.g. Fleeting Vigor)\r\n\t// Minions in hand (e.g. Flighty Scout)\r\n\t// Minions in play (e.g. Promo-Drake)\r\n\tconst phases: readonly StartOfCombatPhase[] = [\r\n\t\t'QuestReward',\r\n\t\t'Anomalies',\r\n\t\t'Trinket',\r\n\t\t// https://twitter.com/DCalkosz/status/1488361384320528388?s=20&t=1ECxRZFdjqwEa2fRsXk32Q\r\n\t\t// There’s a certain order for Start of Combat hero powers, rather than “coin flips” where\r\n\t\t// an unlucky trigger order could mess up some positioning you had planned for your own hero\r\n\t\t// power. “Precombat” (Al’Akir, Y’Shaarj), then Illidan, then others.\r\n\t\t// Update: this seems to have changed: https://x.com/LoewenMitchell/status/1737588920139825335?s=20\r\n\t\t// now you have all hero powers trigger in a first phase, then you have Illidan, and once everything has triggered, you have Tavish\r\n\t\t// All Hero powers are split up in to 3 categories:\r\n\t\t// 1st - Precombat Hero Power Triggers (things we want to go before Illidan e.g. Lich King). Should be Lich King, Teron, Brukan\r\n\t\t// 2nd - Hero Power Triggers First In Combat (Illidan)\r\n\t\t// 3rd - All other Start of Combat Hero Powers\r\n\t\t'PreCombatHeroPower',\r\n\t\t'IllidanHeroPower',\r\n\t\t'HeroPower',\r\n\t\t'Secret',\r\n\t\t'Minion',\r\n\t];\r\n\tlet playerBoardBefore = playerBoard.map((e) => ({ ...e }));\r\n\tlet opponentBoardBefore = opponentBoard.map((e) => ({ ...e }));\r\n\r\n\tlet forcedAttacker = null;\r\n\tfor (const phase of phases) {\r\n\t\tconst { attacker: newAttacker, force: newForce } = handlePhase(\r\n\t\t\tphase,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerBoardBefore,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentBoardBefore,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tcurrentAttacker = newAttacker;\r\n\t\tif (newForce) {\r\n\t\t\tforcedAttacker = newAttacker;\r\n\t\t}\r\n\t\tif (phase === 'PreCombatHeroPower') {\r\n\t\t\tplayerBoardBefore = playerBoard.map((e) => ({ ...e }));\r\n\t\t\topponentBoardBefore = opponentBoard.map((e) => ({ ...e }));\r\n\t\t}\r\n\t}\r\n\tplayerEntity.startOfCombatDone = true;\r\n\topponentEntity.startOfCombatDone = true;\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tresolvePendingEffects(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\treturn forcedAttacker != null ? forcedAttacker : currentAttacker;\r\n};\r\n\r\nconst handlePhase = (\r\n\tphase: StartOfCombatPhase,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerBoardBefore: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentBoardBefore: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tgameState: FullGameState,\r\n): { attacker: number; force: boolean } => {\r\n\tswitch (phase) {\r\n\t\tcase 'QuestReward':\r\n\t\t\tcurrentAttacker = handleStartOfCombatQuestRewards(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Anomalies':\r\n\t\t\tcurrentAttacker = handleStartOfCombatAnomalies(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Trinket':\r\n\t\t\tcurrentAttacker = handleStartOfCombatTrinkets(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'PreCombatHeroPower':\r\n\t\t\tcurrentAttacker = handlePreCombatHeroPowers(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'IllidanHeroPower':\r\n\t\t\tconst { attacker: newAttacker, force: newForce } = handleIllidanHeroPowers(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: newAttacker, force: newForce };\r\n\t\tcase 'HeroPower':\r\n\t\t\tcurrentAttacker = handleStartOfCombatHeroPowers(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Secret':\r\n\t\t\tcurrentAttacker = handleStartOfCombatSecrets(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Minion':\r\n\t\t\tcurrentAttacker = handleStartOfCombatMinions(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tplayerBoardBefore,\r\n\t\t\t\topponentBoardBefore,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t}\r\n\r\n\treturn { attacker: currentAttacker, force: false };\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"start-of-combat.js","sourceRoot":"","sources":["../../../src/simulation/start-of-combat/start-of-combat.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\r\nimport { BgsPlayerEntity } from '../../bgs-player-entity';\r\nimport { BoardEntity } from '../../board-entity';\r\nimport { stampOnBoardDeityAuras } from '../deity';\r\nimport { FullGameState } from '../internal-game-state';\r\nimport { resolvePendingEffects } from '../pending-effects';\r\nimport { applyAfterStatsUpdate } from '../stats';\r\nimport { StartOfCombatPhase } from './phases';\r\nimport { handleStartOfCombatAnomalies } from './soc-anomalies';\r\nimport { handleStartOfCombatHeroPowers } from './soc-hero-power';\r\nimport { handleIllidanHeroPowers } from './soc-illidan-hero-power';\r\nimport { handleStartOfCombatMinions } from './soc-minion';\r\nimport { handlePreCombatHeroPowers } from './soc-pre-combat-hero-power';\r\nimport { handleStartOfCombatQuestRewards } from './soc-quest-reward';\r\nimport { handleStartOfCombatSecrets } from './soc-secret';\r\nimport { handleStartOfCombatTrinkets } from './soc-trinket';\r\n\r\n// TODO 20/04/2024: I'm not too sure about some ordering. The way I understand it, the Start of Combat has\r\n// multiple phases, and in each phase the player order is random\r\n// However, looking at http://replays.firestoneapp.com/?reviewId=a577602e-06f3-4c4b-928d-36ea98c2e6d5&turn=5&action=0,\r\n// it feels that a \"start of combat\" minion effect could trigger before an opponent's hero power effect\r\n// Or is that limited to Bru'kan?\r\n// I feel that I've asked a lot of questions recently, so I don't want to add that one to the list, as the interaction\r\n// is for now pretty marginal\r\nexport const handleStartOfCombat = (\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tgameState: FullGameState,\r\n): number => {\r\n\tstampOnBoardDeityAuras(playerBoard, playerEntity, gameState.allCards);\r\n\tstampOnBoardDeityAuras(opponentBoard, opponentEntity, gameState.allCards);\r\n\r\n\tconst shouldRecomputeCurrentAttacker = true;\r\n\tif (shouldRecomputeCurrentAttacker) {\r\n\t\tcurrentAttacker =\r\n\t\t\tplayerBoard.length > opponentBoard.length\r\n\t\t\t\t? 0\r\n\t\t\t\t: opponentBoard.length > playerBoard.length\r\n\t\t\t\t? 1\r\n\t\t\t\t: Math.round(Math.random());\r\n\t}\r\n\r\n\t// UPDATE 2024-10-10: changed in 30.6, according to a message from Mitchell on Discord\r\n\t// UPDATE 2026-02-21:\r\n\t// K I double checked in-game and documentation and this is the trigger order:\r\n\t// Trinket/Quest Reward\r\n\t// Pre-combat hero powers (e.g. Lich King)\r\n\t// Combat First hero powers (e.g. Illidan)\r\n\t// Start of combat hero powers (e.g. Basically all other hero powers)\r\n\t// Spells (e.g. Fleeting Vigor)\r\n\t// Minions in hand (e.g. Flighty Scout)\r\n\t// Minions in play (e.g. Promo-Drake)\r\n\tconst phases: readonly StartOfCombatPhase[] = [\r\n\t\t'QuestReward',\r\n\t\t'Anomalies',\r\n\t\t'Trinket',\r\n\t\t// https://twitter.com/DCalkosz/status/1488361384320528388?s=20&t=1ECxRZFdjqwEa2fRsXk32Q\r\n\t\t// There’s a certain order for Start of Combat hero powers, rather than “coin flips” where\r\n\t\t// an unlucky trigger order could mess up some positioning you had planned for your own hero\r\n\t\t// power. “Precombat” (Al’Akir, Y’Shaarj), then Illidan, then others.\r\n\t\t// Update: this seems to have changed: https://x.com/LoewenMitchell/status/1737588920139825335?s=20\r\n\t\t// now you have all hero powers trigger in a first phase, then you have Illidan, and once everything has triggered, you have Tavish\r\n\t\t// All Hero powers are split up in to 3 categories:\r\n\t\t// 1st - Precombat Hero Power Triggers (things we want to go before Illidan e.g. Lich King). Should be Lich King, Teron, Brukan\r\n\t\t// 2nd - Hero Power Triggers First In Combat (Illidan)\r\n\t\t// 3rd - All other Start of Combat Hero Powers\r\n\t\t'PreCombatHeroPower',\r\n\t\t'IllidanHeroPower',\r\n\t\t'HeroPower',\r\n\t\t'Secret',\r\n\t\t'Minion',\r\n\t];\r\n\tlet playerBoardBefore = playerBoard.map((e) => ({ ...e }));\r\n\tlet opponentBoardBefore = opponentBoard.map((e) => ({ ...e }));\r\n\r\n\tlet forcedAttacker = null;\r\n\tfor (const phase of phases) {\r\n\t\tconst { attacker: newAttacker, force: newForce } = handlePhase(\r\n\t\t\tphase,\r\n\t\t\tplayerEntity,\r\n\t\t\tplayerBoard,\r\n\t\t\tplayerBoardBefore,\r\n\t\t\topponentEntity,\r\n\t\t\topponentBoard,\r\n\t\t\topponentBoardBefore,\r\n\t\t\tcurrentAttacker,\r\n\t\t\tgameState,\r\n\t\t);\r\n\t\tcurrentAttacker = newAttacker;\r\n\t\tif (newForce) {\r\n\t\t\tforcedAttacker = newAttacker;\r\n\t\t}\r\n\t\tif (phase === 'PreCombatHeroPower') {\r\n\t\t\tplayerBoardBefore = playerBoard.map((e) => ({ ...e }));\r\n\t\t\topponentBoardBefore = opponentBoard.map((e) => ({ ...e }));\r\n\t\t}\r\n\t}\r\n\tplayerEntity.startOfCombatDone = true;\r\n\topponentEntity.startOfCombatDone = true;\r\n\tapplyAfterStatsUpdate(gameState);\r\n\tresolvePendingEffects(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);\r\n\treturn forcedAttacker != null ? forcedAttacker : currentAttacker;\r\n};\r\n\r\nconst handlePhase = (\r\n\tphase: StartOfCombatPhase,\r\n\tplayerEntity: BgsPlayerEntity,\r\n\tplayerBoard: BoardEntity[],\r\n\tplayerBoardBefore: BoardEntity[],\r\n\topponentEntity: BgsPlayerEntity,\r\n\topponentBoard: BoardEntity[],\r\n\topponentBoardBefore: BoardEntity[],\r\n\tcurrentAttacker: number,\r\n\tgameState: FullGameState,\r\n): { attacker: number; force: boolean } => {\r\n\tswitch (phase) {\r\n\t\tcase 'QuestReward':\r\n\t\t\tcurrentAttacker = handleStartOfCombatQuestRewards(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Anomalies':\r\n\t\t\tcurrentAttacker = handleStartOfCombatAnomalies(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Trinket':\r\n\t\t\tcurrentAttacker = handleStartOfCombatTrinkets(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'PreCombatHeroPower':\r\n\t\t\tcurrentAttacker = handlePreCombatHeroPowers(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'IllidanHeroPower':\r\n\t\t\tconst { attacker: newAttacker, force: newForce } = handleIllidanHeroPowers(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: newAttacker, force: newForce };\r\n\t\tcase 'HeroPower':\r\n\t\t\tcurrentAttacker = handleStartOfCombatHeroPowers(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Secret':\r\n\t\t\tcurrentAttacker = handleStartOfCombatSecrets(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t\tcase 'Minion':\r\n\t\t\tcurrentAttacker = handleStartOfCombatMinions(\r\n\t\t\t\tplayerEntity,\r\n\t\t\t\tplayerBoard,\r\n\t\t\t\topponentEntity,\r\n\t\t\t\topponentBoard,\r\n\t\t\t\tcurrentAttacker,\r\n\t\t\t\tplayerBoardBefore,\r\n\t\t\t\topponentBoardBefore,\r\n\t\t\t\tgameState,\r\n\t\t\t);\r\n\t\t\treturn { attacker: currentAttacker, force: false };\r\n\t}\r\n\r\n\treturn { attacker: currentAttacker, force: false };\r\n};\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulation-result.js","sourceRoot":"","sources":["../src/simulation-result.ts"],"names":[],"mappings":"","sourcesContent":["import { GameSample } from './simulation/spectator/game-sample';\r\n\r\nexport interface SimulationResult {\r\n\twonLethal: number;\r\n\twon: number;\r\n\ttied: number;\r\n\tlost: number;\r\n\tlostLethal: number;\r\n\tdamageWon: number;\r\n\tdamageWons: number[];\r\n\tdamageWonRange: {\r\n\t\tmin: number;\r\n\t\tmax: number;\r\n\t};\r\n\tdamageLost: number;\r\n\tdamageLosts: number[];\r\n\tdamageLostRange: {\r\n\t\tmin: number;\r\n\t\tmax: number;\r\n\t};\r\n\twonLethalPercent: number;\r\n\twonPercent: number;\r\n\ttiedPercent: number;\r\n\tlostPercent: number;\r\n\tlostLethalPercent: number;\r\n\taverageDamageWon: number;\r\n\taverageDamageLost: number;\r\n\toutcomeSamples?: OutcomeSamples;\r\n\t/** Package version of the simulator build that produced this result. */\r\n\tsimulatorVersion?: string;\r\n}\r\n\r\nexport interface OutcomeSamples {\r\n\twon: readonly GameSample[];\r\n\tlost: readonly GameSample[];\r\n\ttied: readonly GameSample[];\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"simulation-result.js","sourceRoot":"","sources":["../src/simulation-result.ts"],"names":[],"mappings":"","sourcesContent":["import { GameSample } from './simulation/spectator/game-sample';\r\n\r\nexport interface SimulationResult {\r\n\twonLethal: number;\r\n\twon: number;\r\n\ttied: number;\r\n\tlost: number;\r\n\tlostLethal: number;\r\n\tdamageWon: number;\r\n\tdamageWons: number[];\r\n\tdamageWonRange: {\r\n\t\tmin: number;\r\n\t\tmax: number;\r\n\t};\r\n\tdamageLost: number;\r\n\tdamageLosts: number[];\r\n\tdamageLostRange: {\r\n\t\tmin: number;\r\n\t\tmax: number;\r\n\t};\r\n\twonLethalPercent: number;\r\n\twonPercent: number;\r\n\ttiedPercent: number;\r\n\tlostPercent: number;\r\n\tlostLethalPercent: number;\r\n\taverageDamageWon: number;\r\n\taverageDamageLost: number;\r\n\toutcomeSamples?: OutcomeSamples;\r\n\t/** Package version of the simulator build that produced this result. */\r\n\tsimulatorVersion?: string;\r\n\t/** Hash of the boards and game state passed into this simulation. */\r\n\tinputHash?: string;\r\n}\r\n\r\nexport interface OutcomeSamples {\r\n\twon: readonly GameSample[];\r\n\tlost: readonly GameSample[];\r\n\ttied: readonly GameSample[];\r\n}\r\n"]}
|