@firestone-hs/simulate-bgs-battle 1.1.466 → 1.1.468

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.
Files changed (77) hide show
  1. package/dist/bgs-player-entity.d.ts +12 -1
  2. package/dist/bgs-player-entity.js.map +1 -1
  3. package/dist/cards/cards-data.d.ts +0 -1
  4. package/dist/cards/cards-data.js +18 -50
  5. package/dist/cards/cards-data.js.map +1 -1
  6. package/dist/divine-shield.d.ts +6 -0
  7. package/dist/divine-shield.js +100 -0
  8. package/dist/divine-shield.js.map +1 -0
  9. package/dist/input-sanitation.js +3 -2
  10. package/dist/input-sanitation.js.map +1 -1
  11. package/dist/simulate-bgs-battle.js +3 -0
  12. package/dist/simulate-bgs-battle.js.map +1 -1
  13. package/dist/simulation/add-minion-to-board.d.ts +2 -5
  14. package/dist/simulation/add-minion-to-board.js +172 -45
  15. package/dist/simulation/add-minion-to-board.js.map +1 -1
  16. package/dist/simulation/attack.js +30 -60
  17. package/dist/simulation/attack.js.map +1 -1
  18. package/dist/simulation/auras.d.ts +2 -0
  19. package/dist/simulation/auras.js +60 -23
  20. package/dist/simulation/auras.js.map +1 -1
  21. package/dist/simulation/avenge.js +36 -7
  22. package/dist/simulation/avenge.js.map +1 -1
  23. package/dist/simulation/battlecries.js +53 -12
  24. package/dist/simulation/battlecries.js.map +1 -1
  25. package/dist/simulation/blood-gems.d.ts +2 -2
  26. package/dist/simulation/blood-gems.js +28 -5
  27. package/dist/simulation/blood-gems.js.map +1 -1
  28. package/dist/simulation/cards-in-hand.js +1 -1
  29. package/dist/simulation/cards-in-hand.js.map +1 -1
  30. package/dist/simulation/damage-effects.js +14 -2
  31. package/dist/simulation/damage-effects.js.map +1 -1
  32. package/dist/simulation/damage-to-hero.d.ts +4 -0
  33. package/dist/simulation/damage-to-hero.js +8 -0
  34. package/dist/simulation/damage-to-hero.js.map +1 -0
  35. package/dist/simulation/death-effects.js +15 -0
  36. package/dist/simulation/death-effects.js.map +1 -1
  37. package/dist/simulation/deathrattle-effects.js +58 -27
  38. package/dist/simulation/deathrattle-effects.js.map +1 -1
  39. package/dist/simulation/deathrattle-orchestration.js +3 -3
  40. package/dist/simulation/deathrattle-orchestration.js.map +1 -1
  41. package/dist/simulation/deathrattle-spawns.js +32 -5
  42. package/dist/simulation/deathrattle-spawns.js.map +1 -1
  43. package/dist/simulation/frenzy.js +2 -2
  44. package/dist/simulation/frenzy.js.map +1 -1
  45. package/dist/simulation/minion-death.d.ts +1 -1
  46. package/dist/simulation/minion-death.js +47 -9
  47. package/dist/simulation/minion-death.js.map +1 -1
  48. package/dist/simulation/on-attack.js +11 -4
  49. package/dist/simulation/on-attack.js.map +1 -1
  50. package/dist/simulation/on-being-attacked.js +3 -2
  51. package/dist/simulation/on-being-attacked.js.map +1 -1
  52. package/dist/simulation/reborn.js +9 -0
  53. package/dist/simulation/reborn.js.map +1 -1
  54. package/dist/simulation/remove-minion-from-board.d.ts +2 -1
  55. package/dist/simulation/remove-minion-from-board.js +9 -7
  56. package/dist/simulation/remove-minion-from-board.js.map +1 -1
  57. package/dist/simulation/spawn-fail.d.ts +4 -0
  58. package/dist/simulation/spawn-fail.js +28 -0
  59. package/dist/simulation/spawn-fail.js.map +1 -0
  60. package/dist/simulation/spawns.js +2 -4
  61. package/dist/simulation/spawns.js.map +1 -1
  62. package/dist/simulation/spectator/spectator.d.ts +2 -2
  63. package/dist/simulation/spectator/spectator.js.map +1 -1
  64. package/dist/simulation/start-of-combat.d.ts +1 -1
  65. package/dist/simulation/start-of-combat.js +283 -45
  66. package/dist/simulation/start-of-combat.js.map +1 -1
  67. package/dist/simulation/stats.js +2 -2
  68. package/dist/simulation/stats.js.map +1 -1
  69. package/dist/simulation/summon-when-space.js +39 -0
  70. package/dist/simulation/summon-when-space.js.map +1 -1
  71. package/dist/simulation/utils/golden.d.ts +1 -1
  72. package/dist/simulation/utils/golden.js +2 -2
  73. package/dist/simulation/utils/golden.js.map +1 -1
  74. package/dist/utils.d.ts +7 -8
  75. package/dist/utils.js +73 -53
  76. package/dist/utils.js.map +1 -1
  77. package/package.json +1 -1
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.performStartOfCombatMinionsForPlayer = exports.getHeroPowerForHero = exports.handleStartOfCombatHeroPowers = exports.handleIllidanHeroPowers = exports.handleStartOfCombat = void 0;
4
4
  const reference_data_1 = require("@firestone-hs/reference-data");
5
+ const divine_shield_1 = require("../divine-shield");
5
6
  const utils_1 = require("../services/utils");
6
7
  const utils_2 = require("../utils");
7
8
  const add_minion_to_board_1 = require("./add-minion-to-board");
@@ -15,6 +16,16 @@ const stats_1 = require("./stats");
15
16
  const summon_when_space_1 = require("./summon-when-space");
16
17
  const golden_1 = require("./utils/golden");
17
18
  const handleStartOfCombat = (playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState) => {
19
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
20
+ const shouldRecomputeCurrentAttacker = true;
21
+ if (shouldRecomputeCurrentAttacker) {
22
+ currentAttacker =
23
+ playerBoard.length > opponentBoard.length
24
+ ? 0
25
+ : opponentBoard.length > playerBoard.length
26
+ ? 1
27
+ : Math.round(Math.random());
28
+ }
18
29
  currentAttacker = handleStartOfCombatQuestRewards(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState);
19
30
  currentAttacker = handleStartOfCombatAnomalies(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState);
20
31
  currentAttacker = handlePreCombatHeroPowers(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState);
@@ -39,6 +50,7 @@ const handlePreCombatHeroPowers = (playerEntity, playerBoard, opponentEntity, op
39
50
  currentAttacker = handlePreCombatHeroPowersForPlayer(opponentEntity, opponentBoard, playerEntity, playerBoard, currentAttacker, false, gameState);
40
51
  currentAttacker = handlePreCombatHeroPowersForPlayer(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, true, gameState);
41
52
  }
53
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
42
54
  return currentAttacker;
43
55
  };
44
56
  const handlePreCombatHeroPowersForPlayer = (playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, friendly, gameState) => {
@@ -111,29 +123,39 @@ const handleIllidanHeroPowers = (playerEntity, playerBoard, opponentEntity, oppo
111
123
  currentAttacker = handlePlayerIllidanHeroPowers(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, true, gameState);
112
124
  }
113
125
  (0, attack_1.processMinionDeath)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
126
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
114
127
  return currentAttacker;
115
128
  };
116
129
  exports.handleIllidanHeroPowers = handleIllidanHeroPowers;
117
130
  const handleStartOfCombatMinions = (playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, playerBoardBefore, opponentBoardBefore, gameState) => {
118
- let attackerForStart = currentAttacker;
131
+ let attackerForStart = Math.random() < 0.5 ? 0 : 1;
119
132
  const playerAttackers = [...playerBoard];
120
133
  const opponentAttackers = [...opponentBoard];
121
134
  while (playerAttackers.length > 0 || opponentAttackers.length > 0) {
135
+ let shouldUpdateNextPlayer = false;
122
136
  if (attackerForStart === 0 && playerAttackers.length > 0) {
123
137
  const attacker = playerAttackers.splice(0, 1)[0];
124
138
  if (attacker.health <= 0 || attacker.definitelyDead) {
125
139
  continue;
126
140
  }
127
- (0, exports.performStartOfCombatMinionsForPlayer)(attacker, playerBoard, playerEntity, opponentBoard, opponentEntity, playerBoardBefore, opponentBoardBefore, gameState);
141
+ shouldUpdateNextPlayer = (0, exports.performStartOfCombatMinionsForPlayer)(attacker, playerBoard, playerEntity, opponentBoard, opponentEntity, playerBoardBefore, opponentBoardBefore, gameState);
142
+ }
143
+ else if (attackerForStart === 0 && playerAttackers.length === 0) {
144
+ shouldUpdateNextPlayer = true;
128
145
  }
129
146
  else if (attackerForStart === 1 && opponentAttackers.length > 0) {
130
147
  const attacker = opponentAttackers.splice(0, 1)[0];
131
148
  if (attacker.health <= 0 || attacker.definitelyDead) {
132
149
  continue;
133
150
  }
134
- (0, exports.performStartOfCombatMinionsForPlayer)(attacker, opponentBoard, opponentEntity, playerBoard, playerEntity, opponentBoardBefore, playerBoardBefore, gameState);
151
+ shouldUpdateNextPlayer = (0, exports.performStartOfCombatMinionsForPlayer)(attacker, opponentBoard, opponentEntity, playerBoard, playerEntity, opponentBoardBefore, playerBoardBefore, gameState);
152
+ }
153
+ else if (attackerForStart === 1 && opponentAttackers.length === 0) {
154
+ shouldUpdateNextPlayer = true;
155
+ }
156
+ if (shouldUpdateNextPlayer) {
157
+ attackerForStart = (attackerForStart + 1) % 2;
135
158
  }
136
- attackerForStart = (attackerForStart + 1) % 2;
137
159
  }
138
160
  return currentAttacker;
139
161
  };
@@ -146,6 +168,7 @@ const handleStartOfCombatQuestRewards = (playerEntity, playerBoard, opponentEnti
146
168
  currentAttacker = handleStartOfCombatQuestRewardsForPlayer(opponentEntity, opponentBoard, playerEntity, playerBoard, currentAttacker, gameState, false);
147
169
  currentAttacker = handleStartOfCombatQuestRewardsForPlayer(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState, true);
148
170
  }
171
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
149
172
  return currentAttacker;
150
173
  };
151
174
  const handleStartOfCombatSpells = (playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState) => {
@@ -157,18 +180,208 @@ const handleStartOfCombatSpells = (playerEntity, playerBoard, opponentEntity, op
157
180
  currentAttacker = handleStartOfCombatSpellsForPlayer(opponentEntity, opponentBoard, playerEntity, playerBoard, currentAttacker, gameState);
158
181
  currentAttacker = handleStartOfCombatSpellsForPlayer(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState);
159
182
  }
183
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
160
184
  return currentAttacker;
161
185
  };
162
186
  const handleStartOfCombatAnomalies = (playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState) => {
163
187
  currentAttacker = handleStartOfCombatAnomaliesForPlayer(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState);
164
188
  currentAttacker = handleStartOfCombatAnomaliesForPlayer(opponentEntity, opponentBoard, playerEntity, playerBoard, currentAttacker, gameState);
189
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
165
190
  return currentAttacker;
166
191
  };
167
192
  const handleStartOfCombatQuestRewardsForPlayer = (playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, gameState, playerIsFriendly) => {
168
- var _a;
169
- if (!((_a = playerEntity.questRewards) === null || _a === void 0 ? void 0 : _a.length) || playerEntity.startOfCombatDone) {
193
+ var _a, _b;
194
+ if (playerEntity.startOfCombatDone) {
170
195
  return currentAttacker;
171
196
  }
197
+ for (const trinket of playerEntity.trinkets) {
198
+ switch (trinket.cardId) {
199
+ case "BG30_MagicItem_902":
200
+ if (playerBoard.length > 0) {
201
+ (0, divine_shield_1.updateDivineShield)(playerBoard[0], playerBoard, playerEntity, opponentEntity, true, gameState);
202
+ gameState.spectator.registerPowerTarget(playerEntity, playerBoard[0], playerBoard, null, null);
203
+ if (playerBoard.length > 1) {
204
+ (0, divine_shield_1.updateDivineShield)(playerBoard[1], playerBoard, playerEntity, opponentEntity, true, gameState);
205
+ gameState.spectator.registerPowerTarget(playerEntity, playerBoard[1], playerBoard, null, null);
206
+ }
207
+ }
208
+ break;
209
+ case "BG30_MagicItem_962":
210
+ if (playerBoard.length > 0) {
211
+ const minionsByAttack = [...playerBoard].sort((a, b) => a.attack - b.attack);
212
+ const firstTarget = minionsByAttack[0];
213
+ (0, stats_1.setEntityStats)(firstTarget, 2 * firstTarget.maxAttack, 2 * firstTarget.maxHealth, playerBoard, playerEntity, gameState);
214
+ if (playerBoard.length > 1) {
215
+ const secondTarget = minionsByAttack[1];
216
+ (0, stats_1.setEntityStats)(secondTarget, 2 * secondTarget.maxAttack, 2 * secondTarget.maxHealth, playerBoard, playerEntity, gameState);
217
+ }
218
+ }
219
+ break;
220
+ case "BG30_MagicItem_970":
221
+ case "BG30_MagicItem_970t":
222
+ const medallionBuff = trinket.cardId === "BG30_MagicItem_970" ? 2 : 5;
223
+ (0, utils_2.addStatsToBoard)(trinket, playerBoard, playerEntity, medallionBuff, medallionBuff, gameState);
224
+ break;
225
+ case "BG30_MagicItem_542":
226
+ const highestAttack = Math.max(...playerBoard.map((entity) => entity.attack));
227
+ playerBoard
228
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, playerEntity, reference_data_1.Race.DRAGON, gameState.allCards))
229
+ .forEach((e) => {
230
+ (0, stats_1.setEntityStats)(e, highestAttack, null, playerBoard, playerEntity, gameState);
231
+ });
232
+ break;
233
+ case "BG30_MagicItem_952":
234
+ const elementals = (0, utils_1.shuffleArray)(playerBoard.filter((e) => (0, utils_2.hasCorrectTribe)(e, playerEntity, reference_data_1.Race.ELEMENTAL, gameState.allCards)));
235
+ const targets = elementals.slice(0, 2);
236
+ targets.forEach((e) => {
237
+ var _a;
238
+ e.enchantments = (_a = e.enchantments) !== null && _a !== void 0 ? _a : [];
239
+ e.enchantments.push({
240
+ cardId: "BG30_MagicItem_952e",
241
+ originEntityId: trinket.entityId,
242
+ repeats: 1,
243
+ timing: gameState.sharedState.currentEntityId++,
244
+ });
245
+ gameState.spectator.registerPowerTarget(playerEntity, e, playerBoard, null, null);
246
+ });
247
+ break;
248
+ case "BG30_MagicItem_917":
249
+ playerBoard
250
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, playerEntity, reference_data_1.Race.NAGA, gameState.allCards))
251
+ .forEach((e) => {
252
+ var _a;
253
+ e.enchantments = (_a = e.enchantments) !== null && _a !== void 0 ? _a : [];
254
+ e.enchantments.push({
255
+ cardId: "BG30_MagicItem_917e",
256
+ originEntityId: trinket.entityId,
257
+ repeats: 1,
258
+ timing: gameState.sharedState.currentEntityId++,
259
+ });
260
+ });
261
+ break;
262
+ case "BG30_MagicItem_411":
263
+ playerBoard
264
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, playerEntity, reference_data_1.Race.QUILBOAR, gameState.allCards))
265
+ .forEach((e) => {
266
+ var _a;
267
+ e.enchantments = (_a = e.enchantments) !== null && _a !== void 0 ? _a : [];
268
+ e.enchantments.push({
269
+ cardId: "BG30_MagicItem_411e",
270
+ originEntityId: trinket.entityId,
271
+ repeats: 1,
272
+ timing: gameState.sharedState.currentEntityId++,
273
+ });
274
+ });
275
+ break;
276
+ case "BG30_MagicItem_303":
277
+ if (playerBoard.length < 7) {
278
+ const newMinions = (0, deathrattle_spawns_1.spawnEntities)("BG_TTN_401", 1, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState.allCards, gameState.cardsData, gameState.sharedState, gameState.spectator, playerEntity.friendly, true);
279
+ (0, spawns_1.performEntitySpawns)(newMinions, playerBoard, playerEntity, playerEntity, 0, opponentBoard, opponentEntity, gameState);
280
+ }
281
+ break;
282
+ case "BG30_MagicItem_407":
283
+ if (playerBoard.length < 7) {
284
+ const target = (0, utils_1.pickRandom)(gameState.cardsData.pirateSpawns);
285
+ (0, cards_in_hand_1.addCardsInHand)(playerEntity, playerBoard, [target], gameState);
286
+ const newMinions = (0, deathrattle_spawns_1.spawnEntities)(target, 1, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState.allCards, gameState.cardsData, gameState.sharedState, gameState.spectator, playerEntity.friendly, false);
287
+ const spawns = (0, spawns_1.performEntitySpawns)(newMinions, playerBoard, playerEntity, playerEntity, 0, opponentBoard, opponentEntity, gameState);
288
+ spawns.forEach((spawn) => (spawn.attackImmediately = true));
289
+ }
290
+ break;
291
+ case "BG30_MagicItem_301":
292
+ playerBoard
293
+ .filter((e) => e.cardId === "BG25_008" ||
294
+ e.cardId === "BG25_008_G")
295
+ .forEach((knight) => {
296
+ knight.taunt = true;
297
+ knight.reborn = true;
298
+ gameState.spectator.registerPowerTarget(playerEntity, knight, playerBoard, null, null);
299
+ });
300
+ break;
301
+ case "BG30_MagicItem_822":
302
+ case "BG30_MagicItem_822t2":
303
+ trinket.rememberedMinion = null;
304
+ break;
305
+ case "BG30_MagicItem_989":
306
+ case "BG30_MagicItem_989t":
307
+ const artisanalUrnBuff = trinket.cardId === "BG30_MagicItem_989" ? 3 : 7;
308
+ playerEntity.globalInfo.UndeadAttackBonus =
309
+ ((_a = playerEntity.globalInfo.UndeadAttackBonus) !== null && _a !== void 0 ? _a : 0) + artisanalUrnBuff;
310
+ break;
311
+ case "BG30_MagicItem_310":
312
+ playerBoard
313
+ .filter((e) => e.cardId === "BG25_354" ||
314
+ e.cardId === "BG25_354_G")
315
+ .forEach((e) => (e.stealth = true));
316
+ break;
317
+ case "BG30_MagicItem_441":
318
+ const highestHealthMinionInHand = (_b = playerEntity.hand) === null || _b === void 0 ? void 0 : _b.sort((a, b) => b.health - a.health)[0];
319
+ if (highestHealthMinionInHand && playerBoard.length > 0) {
320
+ (0, stats_1.modifyStats)(playerBoard[0], highestHealthMinionInHand.attack, highestHealthMinionInHand.health, playerBoard, playerEntity, gameState);
321
+ }
322
+ break;
323
+ case "BG30_MagicItem_995":
324
+ if (playerBoard.length > 0) {
325
+ playerBoard.forEach((entity) => {
326
+ const highest = Math.max(entity.attack, entity.health);
327
+ (0, stats_1.setEntityStats)(entity, highest, highest, playerBoard, playerEntity, gameState);
328
+ gameState.spectator.registerPowerTarget(trinket, entity, playerBoard, null, null);
329
+ });
330
+ }
331
+ break;
332
+ case "BG30_MagicItem_403":
333
+ if (playerBoard.length > 0) {
334
+ playerBoard
335
+ .filter((e) => (0, utils_2.getEffectiveTribesForEntity)(e, playerEntity, gameState.allCards).length === 0)
336
+ .forEach((entity) => {
337
+ (0, stats_1.setEntityStats)(entity, 3 * entity.attack, 3 * entity.health, playerBoard, playerEntity, gameState);
338
+ gameState.spectator.registerPowerTarget(trinket, entity, playerBoard, null, null);
339
+ });
340
+ }
341
+ break;
342
+ case "BG30_MagicItem_972":
343
+ if (playerBoard.length > 0) {
344
+ for (let i = 0; i < Math.min(playerBoard.length, 7); i++) {
345
+ const entityToCoy = playerBoard[i];
346
+ const copy = (0, utils_2.copyEntity)(entityToCoy);
347
+ const newMinions = (0, deathrattle_spawns_1.spawnEntities)(copy.cardId, 1, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState.allCards, gameState.cardsData, gameState.sharedState, gameState.spectator, playerEntity.friendly, false, false, false, copy);
348
+ const spawns = (0, spawns_1.performEntitySpawns)(newMinions, playerBoard, playerEntity, playerEntity, playerBoard.length - i - 1, opponentBoard, opponentEntity, gameState);
349
+ i += spawns.length;
350
+ }
351
+ }
352
+ currentAttacker =
353
+ playerBoard.length > opponentBoard.length
354
+ ? playerIsFriendly
355
+ ? 0
356
+ : 1
357
+ : opponentBoard.length > playerBoard.length
358
+ ? playerIsFriendly
359
+ ? 1
360
+ : 0
361
+ : Math.round(Math.random());
362
+ break;
363
+ case "BG30_MagicItem_821":
364
+ case "BG30_MagicItem_821t2":
365
+ if (playerBoard.length < 7) {
366
+ const spawnId = trinket.cardId === "BG30_MagicItem_821"
367
+ ? "TB_BaconShop_HP_105t"
368
+ : "TB_BaconUps_307";
369
+ const newMinions = (0, deathrattle_spawns_1.spawnEntities)(spawnId, 1, playerBoard, playerEntity, opponentBoard, opponentEntity, gameState.allCards, gameState.cardsData, gameState.sharedState, gameState.spectator, playerEntity.friendly, false);
370
+ const spawns = (0, spawns_1.performEntitySpawns)(newMinions, playerBoard, playerEntity, playerEntity, 0, opponentBoard, opponentEntity, gameState);
371
+ currentAttacker =
372
+ playerBoard.length > opponentBoard.length
373
+ ? playerIsFriendly
374
+ ? 0
375
+ : 1
376
+ : opponentBoard.length > playerBoard.length
377
+ ? playerIsFriendly
378
+ ? 1
379
+ : 0
380
+ : Math.round(Math.random());
381
+ }
382
+ break;
383
+ }
384
+ }
172
385
  for (const reward of playerEntity.questRewards) {
173
386
  switch (reward) {
174
387
  case "BG24_Reward_111":
@@ -182,15 +395,16 @@ const handleStartOfCombatQuestRewardsForPlayer = (playerEntity, playerBoard, opp
182
395
  const indexFromRight = playerBoard.length - (playerBoard.indexOf(highestHealthMinion) + 1);
183
396
  (0, spawns_1.performEntitySpawns)(newMinions, playerBoard, playerEntity, highestHealthMinion, indexFromRight, opponentBoard, opponentEntity, gameState);
184
397
  gameState.spectator.registerPowerTarget(playerEntity, copy, playerBoard, null, null);
185
- return playerBoard.length > opponentBoard.length
186
- ? playerIsFriendly
187
- ? 0
188
- : 1
189
- : opponentBoard.length > playerBoard.length
398
+ currentAttacker =
399
+ playerBoard.length > opponentBoard.length
190
400
  ? playerIsFriendly
191
- ? 1
192
- : 0
193
- : Math.round(Math.random());
401
+ ? 0
402
+ : 1
403
+ : opponentBoard.length > playerBoard.length
404
+ ? playerIsFriendly
405
+ ? 1
406
+ : 0
407
+ : Math.round(Math.random());
194
408
  }
195
409
  break;
196
410
  case "BG24_Reward_312":
@@ -201,10 +415,10 @@ const handleStartOfCombatQuestRewardsForPlayer = (playerEntity, playerBoard, opp
201
415
  break;
202
416
  case "BG24_Reward_109":
203
417
  if (playerBoard.length > 0) {
204
- (0, golden_1.makeMinionGolden)(playerBoard[0], playerEntity, playerBoard, playerEntity, gameState);
418
+ (0, golden_1.makeMinionGolden)(playerBoard[0], playerEntity, playerBoard, playerEntity, opponentEntity, gameState);
205
419
  }
206
420
  if (playerBoard.length > 1) {
207
- (0, golden_1.makeMinionGolden)(playerBoard[playerBoard.length - 1], playerEntity, playerBoard, playerEntity, gameState);
421
+ (0, golden_1.makeMinionGolden)(playerBoard[playerBoard.length - 1], playerEntity, playerBoard, playerEntity, opponentEntity, gameState);
208
422
  }
209
423
  break;
210
424
  }
@@ -231,7 +445,6 @@ const handleStartOfCombatSpellsForPlayer = (playerEntity, playerBoard, opponentE
231
445
  break;
232
446
  case "BG28_603":
233
447
  secret.scriptDataNum1 = (_b = secret.scriptDataNum1) !== null && _b !== void 0 ? _b : 1;
234
- (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
235
448
  break;
236
449
  case "BG28_519":
237
450
  (0, utils_2.addStatsToBoard)(secret, playerBoard, playerEntity, 2, 1, gameState);
@@ -257,7 +470,7 @@ const handleStartOfCombatAnomaliesForPlayer = (playerEntity, playerBoard, oppone
257
470
  case "BG27_Anomaly_726":
258
471
  if (playerBoard.length > 0) {
259
472
  const dsTarget = playerBoard[0];
260
- (0, utils_2.updateDivineShield)(dsTarget, playerBoard, true, gameState.allCards);
473
+ (0, divine_shield_1.updateDivineShield)(dsTarget, playerBoard, playerEntity, opponentEntity, true, gameState);
261
474
  const rebornTarget = playerBoard[playerBoard.length - 1];
262
475
  rebornTarget.reborn = true;
263
476
  }
@@ -292,6 +505,7 @@ const handleStartOfCombatHeroPowers = (playerEntity, playerBoard, opponentEntity
292
505
  currentAttacker = handlePlayerStartOfCombatHeroPowers(opponentEntity, opponentBoard, playerEntity, playerBoard, currentAttacker, false, gameState);
293
506
  currentAttacker = handlePlayerStartOfCombatHeroPowers(playerEntity, playerBoard, opponentEntity, opponentBoard, currentAttacker, true, gameState);
294
507
  }
508
+ (0, summon_when_space_1.handleSummonsWhenSpace)(playerBoard, playerEntity, opponentBoard, opponentEntity, gameState);
295
509
  return currentAttacker;
296
510
  };
297
511
  exports.handleStartOfCombatHeroPowers = handleStartOfCombatHeroPowers;
@@ -332,7 +546,7 @@ const handleAlakirForPlayer = (playerBoard, playerEntity, opponentBoard, opponen
332
546
  const firstEntity = playerBoard[0];
333
547
  firstEntity.windfury = true;
334
548
  if (!firstEntity.divineShield) {
335
- (0, utils_2.updateDivineShield)(firstEntity, playerBoard, true, gameState.allCards);
549
+ (0, divine_shield_1.updateDivineShield)(firstEntity, playerBoard, playerEntity, opponentEntity, true, gameState);
336
550
  }
337
551
  firstEntity.taunt = true;
338
552
  gameState.spectator.registerPowerTarget(firstEntity, firstEntity, playerBoard, playerEntity, opponentEntity);
@@ -417,7 +631,7 @@ const handleTeronForPlayer = (playerBoard, playerEntity, opponentBoard, opponent
417
631
  enchantments: (_a = minionThatWillDie.enchantments.map((e) => ({ ...e }))) !== null && _a !== void 0 ? _a : [],
418
632
  pendingAttackBuffs: [],
419
633
  };
420
- (0, add_minion_to_board_1.removeAurasFromSelf)(minionToCopy, playerBoard, playerEntity, gameState.allCards, gameState.sharedState, gameState.spectator);
634
+ (0, add_minion_to_board_1.removeAurasFromSelf)(minionToCopy, playerBoard, playerEntity, gameState);
421
635
  playerEntity.rapidReanimationMinion = minionToCopy;
422
636
  minionThatWillDie.definitelyDead = true;
423
637
  gameState.spectator.registerPowerTarget(playerEntity, minionThatWillDie, playerBoard, playerEntity, opponentEntity);
@@ -427,7 +641,7 @@ const handleTeronForPlayer = (playerBoard, playerEntity, opponentBoard, opponent
427
641
  };
428
642
  const handleWaxWarbandForPlayer = (playerBoard, playerEntity, opponentBoard, opponentEntity, gameState) => {
429
643
  if (playerBoard.length > 0) {
430
- const boardWithTribes = playerBoard.filter((e) => { var _a, _b; return !!((_b = (_a = gameState.allCards.getCard(e.cardId)) === null || _a === void 0 ? void 0 : _a.races) === null || _b === void 0 ? void 0 : _b.length); });
644
+ const boardWithTribes = playerBoard.filter((e) => !!(0, utils_2.getEffectiveTribesForEntity)(e, playerEntity, gameState.allCards).length);
431
645
  const boardWithoutAll = boardWithTribes.filter((e) => !gameState.allCards.getCard(e.cardId).races.includes(reference_data_1.Race[reference_data_1.Race.ALL]));
432
646
  const selectedMinions = selectMinions(boardWithoutAll, reference_data_1.ALL_BG_RACES, gameState.allCards);
433
647
  const allMinions = [
@@ -532,18 +746,15 @@ exports.getHeroPowerForHero = getHeroPowerForHero;
532
746
  const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackingBoardHero, defendingBoard, defendingBoardHero, attackingBoardBefore, defendingBoardBefore, gameState) => {
533
747
  var _a, _b, _c, _d;
534
748
  if (attackingBoardHero.startOfCombatDone) {
535
- return;
749
+ return false;
536
750
  }
751
+ let hasProcessed = true;
537
752
  if (attacker.cardId === "BGS_019") {
538
- const damage = attackingBoardBefore
539
- .map((entity) => gameState.allCards.getCard(entity.cardId).races)
540
- .filter((races) => (0, utils_2.isCorrectTribe)(races, reference_data_1.Race.DRAGON)).length;
753
+ const damage = attackingBoardBefore.filter((entity) => (0, utils_2.hasCorrectTribe)(entity, attackingBoardHero, reference_data_1.Race.DRAGON, gameState.allCards)).length;
541
754
  (0, attack_1.dealDamageToRandomEnemy)(defendingBoard, defendingBoardHero, attacker, damage, attackingBoard, attackingBoardHero, gameState);
542
755
  }
543
756
  else if (attacker.cardId === "TB_BaconUps_102") {
544
- const damage = attackingBoardBefore
545
- .map((entity) => gameState.allCards.getCard(entity.cardId).races)
546
- .filter((races) => (0, utils_2.isCorrectTribe)(races, reference_data_1.Race.DRAGON)).length;
757
+ const damage = attackingBoardBefore.filter((entity) => (0, utils_2.hasCorrectTribe)(entity, attackingBoardHero, reference_data_1.Race.DRAGON, gameState.allCards)).length;
547
758
  (0, attack_1.dealDamageToRandomEnemy)(defendingBoard, defendingBoardHero, attacker, damage, attackingBoard, attackingBoardHero, gameState);
548
759
  (0, attack_1.dealDamageToRandomEnemy)(defendingBoard, defendingBoardHero, attacker, damage, attackingBoard, attackingBoardHero, gameState);
549
760
  }
@@ -552,7 +763,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
552
763
  const stats = attacker.cardId === "BG21_014_G" ? 6 : 3;
553
764
  const targets = attackingBoard
554
765
  .filter((e) => e.entityId !== attacker.entityId)
555
- .filter((e) => (0, utils_2.hasCorrectTribe)(e, reference_data_1.Race.DRAGON, gameState.allCards));
766
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, attackingBoardHero, reference_data_1.Race.DRAGON, gameState.allCards));
556
767
  for (const entity of targets) {
557
768
  (0, stats_1.modifyStats)(entity, stats, stats, attackingBoard, attackingBoardHero, gameState);
558
769
  gameState.spectator.registerPowerTarget(attacker, entity, attackingBoard, attackingBoardHero, defendingBoardHero);
@@ -567,7 +778,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
567
778
  else if (attacker.cardId === "BG24_500" ||
568
779
  attacker.cardId === "BG24_500_G") {
569
780
  const otherDragons = attackingBoard
570
- .filter((e) => (0, utils_2.hasCorrectTribe)(e, reference_data_1.Race.DRAGON, gameState.allCards))
781
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, attackingBoardHero, reference_data_1.Race.DRAGON, gameState.allCards))
571
782
  .filter((e) => e.entityId !== attacker.entityId);
572
783
  const loops = attacker.cardId === "BG24_500_G" ? 2 : 1;
573
784
  const dragonsToConsider = otherDragons;
@@ -575,7 +786,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
575
786
  const otherDragon = (_c = (0, utils_1.pickRandom)(dragonsToConsider.filter((e) => !e.divineShield))) !== null && _c !== void 0 ? _c : (0, utils_1.pickRandom)(dragonsToConsider);
576
787
  if (otherDragon) {
577
788
  if (!otherDragon.divineShield) {
578
- (0, utils_2.updateDivineShield)(otherDragon, attackingBoard, true, gameState.allCards);
789
+ (0, divine_shield_1.updateDivineShield)(otherDragon, attackingBoard, attackingBoardHero, defendingBoardHero, true, gameState);
579
790
  }
580
791
  (0, stats_1.modifyStats)(otherDragon, 7, 7, attackingBoard, attackingBoardHero, gameState);
581
792
  gameState.spectator.registerPowerTarget(attacker, otherDragon, attackingBoard, attackingBoardHero, defendingBoardHero);
@@ -587,7 +798,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
587
798
  attacker.cardId === "BG26_356_G") {
588
799
  const buff = attacker.cardId === "BG26_356_G" ? 16 : 8;
589
800
  const otherDragons = attackingBoard
590
- .filter((e) => (0, utils_2.hasCorrectTribe)(e, reference_data_1.Race.DRAGON, gameState.allCards))
801
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, attackingBoardHero, reference_data_1.Race.DRAGON, gameState.allCards))
591
802
  .filter((e) => e.entityId !== attacker.entityId);
592
803
  otherDragons.forEach((otherDragon) => {
593
804
  (0, stats_1.modifyStats)(otherDragon, 0, buff, attackingBoard, attackingBoardHero, gameState);
@@ -599,7 +810,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
599
810
  const numberOfTargets = attacker.cardId === "BG25_023_G" ? 2 : 1;
600
811
  for (let i = 0; i < numberOfTargets; i++) {
601
812
  const undeadsWithoutReborn = attackingBoard
602
- .filter((e) => (0, utils_2.hasCorrectTribe)(e, reference_data_1.Race.UNDEAD, gameState.allCards))
813
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, attackingBoardHero, reference_data_1.Race.UNDEAD, gameState.allCards))
603
814
  .filter((e) => !e.reborn);
604
815
  const chosenUndead = (0, utils_1.pickRandom)(undeadsWithoutReborn);
605
816
  if (chosenUndead) {
@@ -627,14 +838,15 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
627
838
  else if (attacker.cardId === "BG24_704" ||
628
839
  attacker.cardId === "BG24_704_G") {
629
840
  if (defendingBoard.length > 0) {
630
- const attackerIndex = attackingBoard.indexOf(attacker);
631
- const defenderPosition = attackerIndex - (attackingBoard.length - defendingBoard.length) / 2;
632
- if (Math.round(defenderPosition) === defenderPosition) {
633
- castImpure(defendingBoard[defenderPosition], attacker, attackingBoard, gameState.spectator);
634
- }
635
- else {
636
- castImpure(defendingBoard[defenderPosition - 0.5], attacker, attackingBoard, gameState.spectator);
637
- castImpure(defendingBoard[defenderPosition + 0.5], attacker, attackingBoard, gameState.spectator);
841
+ const validTargets = defendingBoard.filter((e) => gameState.cardsData.getTavernLevel(e.cardId) >= 5);
842
+ const numberOfPicks = attacker.cardId === "BG24_704_G" ? 2 : 1;
843
+ for (let i = 0; i < numberOfPicks; i++) {
844
+ const target = (0, utils_1.pickRandom)(validTargets);
845
+ if (!!target) {
846
+ castImpure(attacker, target, attackingBoard, gameState.spectator);
847
+ const targetIndex = validTargets.findIndex((e) => e.entityId === target.entityId);
848
+ validTargets.splice(targetIndex, 1);
849
+ }
638
850
  }
639
851
  }
640
852
  }
@@ -771,7 +983,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
771
983
  attacker.cardId === "BG29_810_G") {
772
984
  const loops = attacker.cardId === "BG29_810_G" ? 2 : 1;
773
985
  const pickedTargets = [];
774
- const dragons = attackingBoard.filter((e) => (0, utils_2.hasCorrectTribe)(e, reference_data_1.Race.DRAGON, gameState.allCards));
986
+ const dragons = attackingBoard.filter((e) => (0, utils_2.hasCorrectTribe)(e, attackingBoardHero, reference_data_1.Race.DRAGON, gameState.allCards));
775
987
  for (let i = 0; i < loops; i++) {
776
988
  const target = dragons.filter((e) => !pickedTargets.includes(e))[0];
777
989
  if (!!target) {
@@ -794,7 +1006,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
794
1006
  const candidates = randomBoard.sort((a, b) => gameState.cardsData.getTavernLevel(a.cardId) - gameState.cardsData.getTavernLevel(b.cardId));
795
1007
  const target = candidates[0];
796
1008
  if (!!target) {
797
- (0, golden_1.makeMinionGolden)(target, attacker, attackingBoard, attackingBoardHero, gameState);
1009
+ (0, golden_1.makeMinionGolden)(target, attacker, attackingBoard, attackingBoardHero, defendingBoardHero, gameState);
798
1010
  }
799
1011
  }
800
1012
  }
@@ -839,7 +1051,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
839
1051
  const attackerIndex = attackingBoard.indexOf(attacker);
840
1052
  attackingBoard.splice(attackerIndex, 0, copy);
841
1053
  if (isGolden) {
842
- (0, golden_1.makeMinionGolden)(copy, copy, attackingBoard, attackingBoardHero, gameState);
1054
+ (0, golden_1.makeMinionGolden)(copy, copy, attackingBoard, attackingBoardHero, defendingBoardHero, gameState);
843
1055
  }
844
1056
  }
845
1057
  }
@@ -855,7 +1067,7 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
855
1067
  }
856
1068
  else if (attacker.cardId === "TB_BaconShop_HERO_14_Buddy" ||
857
1069
  attacker.cardId === "TB_BaconShop_HERO_14_Buddy_G") {
858
- const minionsOfDifferentTypes = (0, utils_2.getMinionsOfDifferentTypes)(attackingBoard, gameState);
1070
+ const minionsOfDifferentTypes = (0, utils_2.getMinionsOfDifferentTypes)(attackingBoard, attackingBoardHero, gameState);
859
1071
  if (minionsOfDifferentTypes.length >= 4) {
860
1072
  const highestAttackOnBoard = Math.max(...attackingBoard.map((entity) => entity.attack));
861
1073
  const highestHealthOnBoard = Math.max(...attackingBoard.map((entity) => entity.health));
@@ -864,7 +1076,33 @@ const performStartOfCombatMinionsForPlayer = (attacker, attackingBoard, attackin
864
1076
  gameState.spectator.registerPowerTarget(attacker, attacker, attackingBoard, attackingBoardHero, defendingBoardHero);
865
1077
  }
866
1078
  }
1079
+ else if (attacker.cardId === "BG30_101" || attacker.cardId === "BG30_101_G") {
1080
+ if (attackingBoard.length > 0 || defendingBoard.length > 0) {
1081
+ const quantity = attacker.cardId === "BG30_101" ? 3 : 6;
1082
+ (0, divine_shield_1.grantDivineShieldToLeftmostMinions)(attacker, attackingBoard, attackingBoardHero, quantity, defendingBoardHero, gameState);
1083
+ }
1084
+ }
1085
+ else if (attacker.cardId === "BG30_119" ||
1086
+ attacker.cardId === "BG30_119_G") {
1087
+ attackingBoard
1088
+ .filter((e) => e.entityId !== attacker.entityId)
1089
+ .filter((e) => (0, utils_2.hasCorrectTribe)(e, attackingBoardHero, reference_data_1.Race.PIRATE, gameState.allCards))
1090
+ .forEach((e) => {
1091
+ e.enchantments = e.enchantments || [];
1092
+ e.enchantments.push({
1093
+ cardId: attacker.cardId === "BG30_119_G"
1094
+ ? "BG30_119_Ge"
1095
+ : "BG30_119e",
1096
+ originEntityId: attacker.entityId,
1097
+ timing: gameState.sharedState.currentEntityId++,
1098
+ });
1099
+ });
1100
+ }
1101
+ else {
1102
+ hasProcessed = false;
1103
+ }
867
1104
  (0, attack_1.processMinionDeath)(attackingBoard, attackingBoardHero, defendingBoard, defendingBoardHero, gameState);
1105
+ return hasProcessed;
868
1106
  };
869
1107
  exports.performStartOfCombatMinionsForPlayer = performStartOfCombatMinionsForPlayer;
870
1108
  const applyAllWillBurn = (board1, board1Hero, board2, board2Hero, sourceEntity, gameState) => {