@robsonbittencourt/calc 0.10.0

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 (144) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +12 -0
  3. package/bundle +107 -0
  4. package/dist/adaptable.d.ts +6 -0
  5. package/dist/adaptable.js +28 -0
  6. package/dist/adaptable.js.map +1 -0
  7. package/dist/calc.d.ts +6 -0
  8. package/dist/calc.js +26 -0
  9. package/dist/calc.js.map +1 -0
  10. package/dist/data/abilities.d.ts +15 -0
  11. package/dist/data/abilities.js +448 -0
  12. package/dist/data/abilities.js.map +1 -0
  13. package/dist/data/index.d.ts +2 -0
  14. package/dist/data/index.js +30 -0
  15. package/dist/data/index.js.map +1 -0
  16. package/dist/data/interface.d.ts +150 -0
  17. package/dist/data/interface.js +3 -0
  18. package/dist/data/interface.js.map +1 -0
  19. package/dist/data/items.d.ts +24 -0
  20. package/dist/data/items.js +708 -0
  21. package/dist/data/items.js.map +1 -0
  22. package/dist/data/moves.d.ts +86 -0
  23. package/dist/data/moves.js +5014 -0
  24. package/dist/data/moves.js.map +1 -0
  25. package/dist/data/natures.d.ts +17 -0
  26. package/dist/data/natures.js +127 -0
  27. package/dist/data/natures.js.map +1 -0
  28. package/dist/data/production.min.js +1 -0
  29. package/dist/data/species.d.ts +48 -0
  30. package/dist/data/species.js +10126 -0
  31. package/dist/data/species.js.map +1 -0
  32. package/dist/data/types.d.ts +23 -0
  33. package/dist/data/types.js +538 -0
  34. package/dist/data/types.js.map +1 -0
  35. package/dist/desc.d.ts +65 -0
  36. package/dist/desc.js +866 -0
  37. package/dist/desc.js.map +1 -0
  38. package/dist/field.d.ts +49 -0
  39. package/dist/field.js +111 -0
  40. package/dist/field.js.map +1 -0
  41. package/dist/index.d.ts +44 -0
  42. package/dist/index.js +99 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/items.d.ts +13 -0
  45. package/dist/items.js +434 -0
  46. package/dist/items.js.map +1 -0
  47. package/dist/mechanics/gen12.d.ts +6 -0
  48. package/dist/mechanics/gen12.js +271 -0
  49. package/dist/mechanics/gen12.js.map +1 -0
  50. package/dist/mechanics/gen3.d.ts +11 -0
  51. package/dist/mechanics/gen3.js +371 -0
  52. package/dist/mechanics/gen3.js.map +1 -0
  53. package/dist/mechanics/gen4.d.ts +11 -0
  54. package/dist/mechanics/gen4.js +596 -0
  55. package/dist/mechanics/gen4.js.map +1 -0
  56. package/dist/mechanics/gen56.d.ts +13 -0
  57. package/dist/mechanics/gen56.js +836 -0
  58. package/dist/mechanics/gen56.js.map +1 -0
  59. package/dist/mechanics/gen789.d.ts +14 -0
  60. package/dist/mechanics/gen789.js +1325 -0
  61. package/dist/mechanics/gen789.js.map +1 -0
  62. package/dist/mechanics/util.d.ts +39 -0
  63. package/dist/mechanics/util.js +675 -0
  64. package/dist/mechanics/util.js.map +1 -0
  65. package/dist/move.d.ts +50 -0
  66. package/dist/move.js +324 -0
  67. package/dist/move.js.map +1 -0
  68. package/dist/pokemon.d.ts +55 -0
  69. package/dist/pokemon.js +240 -0
  70. package/dist/pokemon.js.map +1 -0
  71. package/dist/production.min.js +1 -0
  72. package/dist/result.d.ts +34 -0
  73. package/dist/result.js +94 -0
  74. package/dist/result.js.map +1 -0
  75. package/dist/state.d.ts +77 -0
  76. package/dist/state.js +3 -0
  77. package/dist/state.js.map +1 -0
  78. package/dist/stats.d.ts +26 -0
  79. package/dist/stats.js +183 -0
  80. package/dist/stats.js.map +1 -0
  81. package/dist/test/calc.test.d.ts +1 -0
  82. package/dist/test/calc.test.js +1297 -0
  83. package/dist/test/calc.test.js.map +1 -0
  84. package/dist/test/data.test.d.ts +1 -0
  85. package/dist/test/data.test.js +368 -0
  86. package/dist/test/data.test.js.map +1 -0
  87. package/dist/test/gen.d.ts +135 -0
  88. package/dist/test/gen.js +636 -0
  89. package/dist/test/gen.js.map +1 -0
  90. package/dist/test/helper.d.ts +55 -0
  91. package/dist/test/helper.js +174 -0
  92. package/dist/test/helper.js.map +1 -0
  93. package/dist/test/move.test.d.ts +1 -0
  94. package/dist/test/move.test.js +14 -0
  95. package/dist/test/move.test.js.map +1 -0
  96. package/dist/test/pokemon.test.d.ts +1 -0
  97. package/dist/test/pokemon.test.js +102 -0
  98. package/dist/test/pokemon.test.js.map +1 -0
  99. package/dist/test/stats.test.d.ts +1 -0
  100. package/dist/test/stats.test.js +64 -0
  101. package/dist/test/stats.test.js.map +1 -0
  102. package/dist/test/utils.test.d.ts +1 -0
  103. package/dist/test/utils.test.js +19 -0
  104. package/dist/test/utils.test.js.map +1 -0
  105. package/dist/util.d.ts +17 -0
  106. package/dist/util.js +115 -0
  107. package/dist/util.js.map +1 -0
  108. package/jest.config.js +11 -0
  109. package/package.json +40 -0
  110. package/src/adaptable.ts +12 -0
  111. package/src/calc.ts +40 -0
  112. package/src/data/abilities.ts +383 -0
  113. package/src/data/index.ts +36 -0
  114. package/src/data/interface.ts +176 -0
  115. package/src/data/items.ts +632 -0
  116. package/src/data/moves.ts +5028 -0
  117. package/src/data/natures.ts +65 -0
  118. package/src/data/species.ts +10098 -0
  119. package/src/data/types.ts +478 -0
  120. package/src/desc.ts +1063 -0
  121. package/src/field.ts +124 -0
  122. package/src/index.ts +156 -0
  123. package/src/items.ts +423 -0
  124. package/src/mechanics/gen12.ts +297 -0
  125. package/src/mechanics/gen3.ts +444 -0
  126. package/src/mechanics/gen4.ts +702 -0
  127. package/src/mechanics/gen56.ts +1134 -0
  128. package/src/mechanics/gen789.ts +1788 -0
  129. package/src/mechanics/util.ts +676 -0
  130. package/src/move.ts +337 -0
  131. package/src/pokemon.ts +244 -0
  132. package/src/result.ts +106 -0
  133. package/src/state.ts +81 -0
  134. package/src/stats.ts +213 -0
  135. package/src/test/calc.test.ts +1588 -0
  136. package/src/test/data.test.ts +129 -0
  137. package/src/test/gen.ts +514 -0
  138. package/src/test/helper.ts +185 -0
  139. package/src/test/move.test.ts +13 -0
  140. package/src/test/pokemon.test.ts +121 -0
  141. package/src/test/stats.test.ts +84 -0
  142. package/src/test/utils.test.ts +18 -0
  143. package/src/util.ts +153 -0
  144. package/tsconfig.json +10 -0
@@ -0,0 +1,1325 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.calculateFinalModsSMSSSV = exports.calculateDfModsSMSSSV = exports.calculateDefenseSMSSSV = exports.calculateAtModsSMSSSV = exports.calculateAttackSMSSSV = exports.calculateBPModsSMSSSV = exports.calculateBasePowerSMSSSV = exports.calculateSMSSSV = void 0;
4
+ var util_1 = require("../util");
5
+ var items_1 = require("../items");
6
+ var result_1 = require("../result");
7
+ var util_2 = require("./util");
8
+ function calculateSMSSSV(gen, attacker, defender, move, field) {
9
+ var _a;
10
+ (0, util_2.checkAirLock)(attacker, field);
11
+ (0, util_2.checkAirLock)(defender, field);
12
+ (0, util_2.checkTeraformZero)(attacker, field);
13
+ (0, util_2.checkTeraformZero)(defender, field);
14
+ (0, util_2.checkForecast)(attacker, field.weather);
15
+ (0, util_2.checkForecast)(defender, field.weather);
16
+ (0, util_2.checkItem)(attacker, field.isMagicRoom);
17
+ (0, util_2.checkItem)(defender, field.isMagicRoom);
18
+ (0, util_2.checkWonderRoom)(attacker, field.isWonderRoom);
19
+ (0, util_2.checkWonderRoom)(defender, field.isWonderRoom);
20
+ (0, util_2.checkSeedBoost)(attacker, field);
21
+ (0, util_2.checkSeedBoost)(defender, field);
22
+ (0, util_2.checkDauntlessShield)(attacker, gen);
23
+ (0, util_2.checkDauntlessShield)(defender, gen);
24
+ (0, util_2.checkEmbody)(attacker, gen);
25
+ (0, util_2.checkEmbody)(defender, gen);
26
+ (0, util_2.computeFinalStats)(gen, attacker, defender, field, 'def', 'spd', 'spe');
27
+ (0, util_2.checkIntimidate)(gen, attacker, defender);
28
+ (0, util_2.checkIntimidate)(gen, defender, attacker);
29
+ (0, util_2.checkDownload)(attacker, defender, field.isWonderRoom);
30
+ (0, util_2.checkDownload)(defender, attacker, field.isWonderRoom);
31
+ (0, util_2.checkIntrepidSword)(attacker, gen);
32
+ (0, util_2.checkIntrepidSword)(defender, gen);
33
+ (0, util_2.checkWindRider)(attacker, field.attackerSide);
34
+ (0, util_2.checkWindRider)(defender, field.defenderSide);
35
+ if (move.named('Meteor Beam', 'Electro Shot')) {
36
+ attacker.boosts.spa +=
37
+ attacker.hasAbility('Simple') ? 2
38
+ : attacker.hasAbility('Contrary') ? -1
39
+ : 1;
40
+ attacker.boosts.spa = Math.min(6, Math.max(-6, attacker.boosts.spa));
41
+ }
42
+ (0, util_2.computeFinalStats)(gen, attacker, defender, field, 'atk', 'spa');
43
+ (0, util_2.checkInfiltrator)(attacker, field.defenderSide);
44
+ (0, util_2.checkInfiltrator)(defender, field.attackerSide);
45
+ var desc = {
46
+ attackerName: attacker.name,
47
+ moveName: move.name,
48
+ defenderName: defender.name,
49
+ isDefenderDynamaxed: defender.isDynamaxed,
50
+ isWonderRoom: field.isWonderRoom
51
+ };
52
+ if (attacker.teraType !== 'Stellar' || move.name === 'Tera Blast' || move.isStellarFirstUse) {
53
+ desc.isStellarFirstUse = attacker.name !== 'Terapagos-Stellar' && move.name === 'Tera Blast' &&
54
+ attacker.teraType === 'Stellar' && move.isStellarFirstUse;
55
+ desc.attackerTera = attacker.teraType;
56
+ }
57
+ if (defender.teraType !== 'Stellar')
58
+ desc.defenderTera = defender.teraType;
59
+ if (move.named('Photon Geyser', 'Light That Burns the Sky') ||
60
+ (move.named('Tera Blast') && attacker.teraType)) {
61
+ move.category = attacker.stats.atk > attacker.stats.spa ? 'Physical' : 'Special';
62
+ }
63
+ var result = new result_1.Result(gen, attacker, defender, move, field, 0, desc);
64
+ if (move.category === 'Status' && !move.named('Nature Power')) {
65
+ return result;
66
+ }
67
+ if (move.flags.punch && attacker.hasItem('Punching Glove')) {
68
+ desc.attackerItem = attacker.item;
69
+ move.flags.contact = 0;
70
+ }
71
+ if (move.named('Shell Side Arm') &&
72
+ (0, util_2.getShellSideArmCategory)(attacker, defender) === 'Physical') {
73
+ move.flags.contact = 1;
74
+ }
75
+ var breaksProtect = move.breaksProtect || move.isZ || attacker.isDynamaxed ||
76
+ (attacker.hasAbility('Unseen Fist') && move.flags.contact);
77
+ if (field.defenderSide.isProtected && !breaksProtect) {
78
+ desc.isProtected = true;
79
+ return result;
80
+ }
81
+ if (move.name === 'Pain Split') {
82
+ var average = Math.floor((attacker.curHP() + defender.curHP()) / 2);
83
+ var damage_1 = Math.max(0, defender.curHP() - average);
84
+ result.damage = damage_1;
85
+ return result;
86
+ }
87
+ var defenderAbilityIgnored = defender.hasAbility('Armor Tail', 'Aroma Veil', 'Aura Break', 'Battle Armor', 'Big Pecks', 'Bulletproof', 'Clear Body', 'Contrary', 'Damp', 'Dazzling', 'Disguise', 'Dry Skin', 'Earth Eater', 'Filter', 'Flash Fire', 'Flower Gift', 'Flower Veil', 'Fluffy', 'Friend Guard', 'Fur Coat', 'Good as Gold', 'Grass Pelt', 'Guard Dog', 'Heatproof', 'Heavy Metal', 'Hyper Cutter', 'Ice Face', 'Ice Scales', 'Illuminate', 'Immunity', 'Inner Focus', 'Insomnia', 'Keen Eye', 'Leaf Guard', 'Levitate', 'Light Metal', 'Lightning Rod', 'Limber', 'Magic Bounce', 'Magma Armor', 'Marvel Scale', "Mind's Eye", 'Mirror Armor', 'Motor Drive', 'Multiscale', 'Oblivious', 'Overcoat', 'Own Tempo', 'Pastel Veil', 'Punk Rock', 'Purifying Salt', 'Queenly Majesty', 'Sand Veil', 'Sap Sipper', 'Shell Armor', 'Shield Dust', 'Simple', 'Snow Cloak', 'Solid Rock', 'Soundproof', 'Sticky Hold', 'Storm Drain', 'Sturdy', 'Suction Cups', 'Sweet Veil', 'Tangled Feet', 'Telepathy', 'Tera Shell', 'Thermal Exchange', 'Thick Fat', 'Unaware', 'Vital Spirit', 'Volt Absorb', 'Water Absorb', 'Water Bubble', 'Water Veil', 'Well-Baked Body', 'White Smoke', 'Wind Rider', 'Wonder Guard', 'Wonder Skin');
88
+ var attackerIgnoresAbility = attacker.hasAbility('Mold Breaker', 'Teravolt', 'Turboblaze');
89
+ var moveIgnoresAbility = move.named('G-Max Drum Solo', 'G-Max Fire Ball', 'G-Max Hydrosnipe', 'Light That Burns the Sky', 'Menacing Moonraze Maelstrom', 'Moongeist Beam', 'Photon Geyser', 'Searing Sunraze Smash', 'Sunsteel Strike');
90
+ if (defenderAbilityIgnored && (attackerIgnoresAbility || moveIgnoresAbility)) {
91
+ if (attackerIgnoresAbility)
92
+ desc.attackerAbility = attacker.ability;
93
+ if (defender.hasItem('Ability Shield')) {
94
+ desc.defenderItem = defender.item;
95
+ }
96
+ else {
97
+ defender.ability = '';
98
+ }
99
+ }
100
+ var ignoresNeutralizingGas = [
101
+ 'As One (Glastrier)', 'As One (Spectrier)', 'Battle Bond', 'Comatose',
102
+ 'Disguise', 'Gulp Missile', 'Ice Face', 'Multitype', 'Neutralizing Gas',
103
+ 'Power Construct', 'RKS System', 'Schooling', 'Shields Down',
104
+ 'Stance Change', 'Tera Shift', 'Zen Mode', 'Zero to Hero',
105
+ ];
106
+ if (attacker.hasAbility('Neutralizing Gas') &&
107
+ !ignoresNeutralizingGas.includes(defender.ability || '')) {
108
+ desc.attackerAbility = attacker.ability;
109
+ if (defender.hasItem('Ability Shield')) {
110
+ desc.defenderItem = defender.item;
111
+ }
112
+ else {
113
+ defender.ability = '';
114
+ }
115
+ }
116
+ if (defender.hasAbility('Neutralizing Gas') &&
117
+ !ignoresNeutralizingGas.includes(attacker.ability || '')) {
118
+ desc.defenderAbility = defender.ability;
119
+ if (attacker.hasItem('Ability Shield')) {
120
+ desc.attackerItem = attacker.item;
121
+ }
122
+ else {
123
+ attacker.ability = '';
124
+ }
125
+ }
126
+ var isCritical = !defender.hasAbility('Battle Armor', 'Shell Armor') &&
127
+ (move.isCrit || (attacker.hasAbility('Merciless') && defender.hasStatus('psn', 'tox'))) &&
128
+ move.timesUsed === 1;
129
+ var type = move.type;
130
+ if (move.originalName === 'Weather Ball') {
131
+ var holdingUmbrella = attacker.hasItem('Utility Umbrella');
132
+ type =
133
+ field.hasWeather('Sun', 'Harsh Sunshine') && !holdingUmbrella ? 'Fire'
134
+ : field.hasWeather('Rain', 'Heavy Rain') && !holdingUmbrella ? 'Water'
135
+ : field.hasWeather('Sand') ? 'Rock'
136
+ : field.hasWeather('Hail', 'Snow') ? 'Ice'
137
+ : 'Normal';
138
+ desc.weather = field.weather;
139
+ desc.moveType = type;
140
+ }
141
+ else if (move.named('Judgment') && attacker.item && attacker.item.includes('Plate')) {
142
+ type = (0, items_1.getItemBoostType)(attacker.item);
143
+ }
144
+ else if (move.originalName === 'Techno Blast' &&
145
+ attacker.item && attacker.item.includes('Drive')) {
146
+ type = (0, items_1.getTechnoBlast)(attacker.item);
147
+ desc.moveType = type;
148
+ }
149
+ else if (move.originalName === 'Multi-Attack' &&
150
+ attacker.item && attacker.item.includes('Memory')) {
151
+ type = (0, items_1.getMultiAttack)(attacker.item);
152
+ desc.moveType = type;
153
+ }
154
+ else if (move.named('Natural Gift') && ((_a = attacker.item) === null || _a === void 0 ? void 0 : _a.endsWith('Berry'))) {
155
+ var gift = (0, items_1.getNaturalGift)(gen, attacker.item);
156
+ type = gift.t;
157
+ desc.moveType = type;
158
+ desc.attackerItem = attacker.item;
159
+ }
160
+ else if (move.named('Nature Power') ||
161
+ (move.originalName === 'Terrain Pulse' && (0, util_2.isGrounded)(attacker, field))) {
162
+ type =
163
+ field.hasTerrain('Electric') ? 'Electric'
164
+ : field.hasTerrain('Grassy') ? 'Grass'
165
+ : field.hasTerrain('Misty') ? 'Fairy'
166
+ : field.hasTerrain('Psychic') ? 'Psychic'
167
+ : 'Normal';
168
+ desc.terrain = field.terrain;
169
+ if (move.isMax) {
170
+ desc.moveType = type;
171
+ }
172
+ if (!(move.named('Nature Power') && attacker.hasAbility('Prankster')) &&
173
+ ((defender.types.includes('Dark') ||
174
+ (field.hasTerrain('Psychic') && (0, util_2.isGrounded)(defender, field))))) {
175
+ desc.moveType = type;
176
+ }
177
+ }
178
+ else if (move.originalName === 'Revelation Dance') {
179
+ if (attacker.teraType) {
180
+ type = attacker.teraType;
181
+ }
182
+ else {
183
+ type = attacker.types[0];
184
+ }
185
+ }
186
+ else if (move.named('Aura Wheel')) {
187
+ if (attacker.named('Morpeko')) {
188
+ type = 'Electric';
189
+ }
190
+ else if (attacker.named('Morpeko-Hangry')) {
191
+ type = 'Dark';
192
+ }
193
+ }
194
+ else if (move.named('Raging Bull')) {
195
+ if (attacker.named('Tauros-Paldea-Combat')) {
196
+ type = 'Fighting';
197
+ }
198
+ else if (attacker.named('Tauros-Paldea-Blaze')) {
199
+ type = 'Fire';
200
+ }
201
+ else if (attacker.named('Tauros-Paldea-Aqua')) {
202
+ type = 'Water';
203
+ }
204
+ field.defenderSide.isReflect = false;
205
+ field.defenderSide.isLightScreen = false;
206
+ field.defenderSide.isAuroraVeil = false;
207
+ }
208
+ else if (move.named('Ivy Cudgel')) {
209
+ if (attacker.name.includes('Ogerpon-Cornerstone')) {
210
+ type = 'Rock';
211
+ }
212
+ else if (attacker.name.includes('Ogerpon-Hearthflame')) {
213
+ type = 'Fire';
214
+ }
215
+ else if (attacker.name.includes('Ogerpon-Wellspring')) {
216
+ type = 'Water';
217
+ }
218
+ }
219
+ else if (move.named('Tera Starstorm') && attacker.name === 'Terapagos-Stellar') {
220
+ move.target = 'allAdjacentFoes';
221
+ type = 'Stellar';
222
+ }
223
+ else if (move.named('Brick Break', 'Psychic Fangs')) {
224
+ field.defenderSide.isReflect = false;
225
+ field.defenderSide.isLightScreen = false;
226
+ field.defenderSide.isAuroraVeil = false;
227
+ }
228
+ var hasAteAbilityTypeChange = false;
229
+ var isAerilate = false;
230
+ var isPixilate = false;
231
+ var isRefrigerate = false;
232
+ var isGalvanize = false;
233
+ var isLiquidVoice = false;
234
+ var isNormalize = false;
235
+ var noTypeChange = move.named('Revelation Dance', 'Judgment', 'Nature Power', 'Techno Blast', 'Multi-Attack', 'Natural Gift', 'Weather Ball', 'Terrain Pulse', 'Struggle') || (move.named('Tera Blast') && attacker.teraType);
236
+ if (!move.isZ && !noTypeChange) {
237
+ var normal = type === 'Normal';
238
+ if ((isAerilate = attacker.hasAbility('Aerilate') && normal)) {
239
+ type = 'Flying';
240
+ }
241
+ else if ((isGalvanize = attacker.hasAbility('Galvanize') && normal)) {
242
+ type = 'Electric';
243
+ }
244
+ else if ((isLiquidVoice = attacker.hasAbility('Liquid Voice') && !!move.flags.sound)) {
245
+ type = 'Water';
246
+ }
247
+ else if ((isPixilate = attacker.hasAbility('Pixilate') && normal)) {
248
+ type = 'Fairy';
249
+ }
250
+ else if ((isRefrigerate = attacker.hasAbility('Refrigerate') && normal)) {
251
+ type = 'Ice';
252
+ }
253
+ else if ((isNormalize = attacker.hasAbility('Normalize'))) {
254
+ type = 'Normal';
255
+ }
256
+ if (isGalvanize || isPixilate || isRefrigerate || isAerilate || isNormalize) {
257
+ desc.attackerAbility = attacker.ability;
258
+ hasAteAbilityTypeChange = true;
259
+ }
260
+ else if (isLiquidVoice) {
261
+ desc.attackerAbility = attacker.ability;
262
+ }
263
+ }
264
+ if (move.named('Tera Blast') && attacker.teraType) {
265
+ type = attacker.teraType;
266
+ }
267
+ move.type = type;
268
+ if ((attacker.hasAbility('Triage') && move.drain) ||
269
+ (attacker.hasAbility('Gale Wings') &&
270
+ move.hasType('Flying') &&
271
+ attacker.curHP() === attacker.maxHP())) {
272
+ move.priority = 1;
273
+ desc.attackerAbility = attacker.ability;
274
+ }
275
+ var isGhostRevealed = attacker.hasAbility('Scrappy') || attacker.hasAbility('Mind\'s Eye') ||
276
+ field.defenderSide.isForesight;
277
+ var isRingTarget = defender.hasItem('Ring Target') && !defender.hasAbility('Klutz');
278
+ var type1Effectiveness = (0, util_2.getMoveEffectiveness)(gen, move, defender.types[0], isGhostRevealed, field.isGravity, isRingTarget);
279
+ var type2Effectiveness = defender.types[1]
280
+ ? (0, util_2.getMoveEffectiveness)(gen, move, defender.types[1], isGhostRevealed, field.isGravity, isRingTarget)
281
+ : 1;
282
+ var typeEffectiveness = type1Effectiveness * type2Effectiveness;
283
+ if (defender.teraType && defender.teraType !== 'Stellar') {
284
+ typeEffectiveness = (0, util_2.getMoveEffectiveness)(gen, move, defender.teraType, isGhostRevealed, field.isGravity, isRingTarget);
285
+ }
286
+ if (typeEffectiveness === 0 && move.hasType('Ground') &&
287
+ defender.hasItem('Iron Ball') && !defender.hasAbility('Klutz')) {
288
+ typeEffectiveness = 1;
289
+ }
290
+ if (typeEffectiveness === 0 && move.named('Thousand Arrows')) {
291
+ typeEffectiveness = 1;
292
+ }
293
+ if (typeEffectiveness === 0) {
294
+ return result;
295
+ }
296
+ if ((move.named('Sky Drop') &&
297
+ (defender.hasType('Flying') || defender.weightkg >= 200 || field.isGravity)) ||
298
+ (move.named('Synchronoise') && !defender.hasType(attacker.types[0]) &&
299
+ (!attacker.types[1] || !defender.hasType(attacker.types[1]))) ||
300
+ (move.named('Dream Eater') &&
301
+ (!(defender.hasStatus('slp') || defender.hasAbility('Comatose')))) ||
302
+ (move.named('Steel Roller') && !field.terrain) ||
303
+ (move.named('Poltergeist') && (!defender.item || (0, util_2.isQPActive)(defender, field)))) {
304
+ return result;
305
+ }
306
+ if ((field.hasWeather('Harsh Sunshine') && move.hasType('Water')) ||
307
+ (field.hasWeather('Heavy Rain') && move.hasType('Fire'))) {
308
+ desc.weather = field.weather;
309
+ return result;
310
+ }
311
+ if (field.hasWeather('Strong Winds') && defender.hasType('Flying') &&
312
+ gen.types.get((0, util_1.toID)(move.type)).effectiveness['Flying'] > 1) {
313
+ typeEffectiveness /= 2;
314
+ desc.weather = field.weather;
315
+ }
316
+ if (move.type === 'Stellar') {
317
+ desc.defenderTera = defender.teraType;
318
+ typeEffectiveness = !defender.teraType ? 1 : 2;
319
+ }
320
+ var turn2typeEffectiveness = typeEffectiveness;
321
+ if (defender.hasAbility('Tera Shell') &&
322
+ defender.curHP() === defender.maxHP() &&
323
+ (!field.defenderSide.isSR && (!field.defenderSide.spikes || defender.hasType('Flying')) ||
324
+ defender.hasItem('Heavy-Duty Boots'))) {
325
+ typeEffectiveness = 0.5;
326
+ desc.defenderAbility = defender.ability;
327
+ }
328
+ if ((defender.hasAbility('Wonder Guard') && typeEffectiveness <= 1) ||
329
+ (move.hasType('Grass') && defender.hasAbility('Sap Sipper')) ||
330
+ (move.hasType('Fire') && defender.hasAbility('Flash Fire', 'Well-Baked Body')) ||
331
+ (move.hasType('Water') && defender.hasAbility('Dry Skin', 'Storm Drain', 'Water Absorb')) ||
332
+ (move.hasType('Electric') &&
333
+ defender.hasAbility('Lightning Rod', 'Motor Drive', 'Volt Absorb')) ||
334
+ (move.hasType('Ground') &&
335
+ !field.isGravity && !move.named('Thousand Arrows') &&
336
+ !defender.hasItem('Iron Ball') && defender.hasAbility('Levitate')) ||
337
+ (move.flags.bullet && defender.hasAbility('Bulletproof')) ||
338
+ (move.flags.sound && !move.named('Clangorous Soul') && defender.hasAbility('Soundproof')) ||
339
+ (move.priority > 0 && defender.hasAbility('Queenly Majesty', 'Dazzling', 'Armor Tail')) ||
340
+ (move.hasType('Ground') && defender.hasAbility('Earth Eater')) ||
341
+ (move.flags.wind && defender.hasAbility('Wind Rider'))) {
342
+ desc.defenderAbility = defender.ability;
343
+ return result;
344
+ }
345
+ if (move.hasType('Ground') && !move.named('Thousand Arrows') &&
346
+ !field.isGravity && defender.hasItem('Air Balloon')) {
347
+ desc.defenderItem = defender.item;
348
+ return result;
349
+ }
350
+ if (move.priority > 0 && field.hasTerrain('Psychic') && (0, util_2.isGrounded)(defender, field)) {
351
+ desc.terrain = field.terrain;
352
+ return result;
353
+ }
354
+ var weightBasedMove = move.named('Heat Crash', 'Heavy Slam', 'Low Kick', 'Grass Knot');
355
+ if (defender.isDynamaxed && weightBasedMove) {
356
+ return result;
357
+ }
358
+ desc.HPEVs = (0, util_2.getStatDescriptionText)(gen, defender, 'hp');
359
+ var fixedDamage = (0, util_2.handleFixedDamageMoves)(attacker, move);
360
+ if (fixedDamage) {
361
+ if (attacker.hasAbility('Parental Bond')) {
362
+ result.damage = [fixedDamage, fixedDamage];
363
+ desc.attackerAbility = attacker.ability;
364
+ }
365
+ else {
366
+ result.damage = fixedDamage;
367
+ }
368
+ return result;
369
+ }
370
+ if (move.named('Final Gambit')) {
371
+ result.damage = attacker.curHP();
372
+ return result;
373
+ }
374
+ if (move.named('Guardian of Alola')) {
375
+ var zLostHP = Math.floor((defender.curHP() * 3) / 4);
376
+ if (field.defenderSide.isProtected && attacker.item && attacker.item.includes(' Z')) {
377
+ zLostHP = Math.ceil(zLostHP / 4 - 0.5);
378
+ }
379
+ result.damage = zLostHP;
380
+ return result;
381
+ }
382
+ if (move.named('Nature\'s Madness')) {
383
+ var lostHP = field.defenderSide.isProtected ? 0 : Math.floor(defender.curHP() / 2);
384
+ result.damage = lostHP;
385
+ return result;
386
+ }
387
+ if (move.named('Spectral Thief')) {
388
+ var stat = void 0;
389
+ for (stat in defender.boosts) {
390
+ if (defender.boosts[stat] > 0) {
391
+ attacker.boosts[stat] +=
392
+ attacker.hasAbility('Contrary') ? -defender.boosts[stat] : defender.boosts[stat];
393
+ if (attacker.boosts[stat] > 6)
394
+ attacker.boosts[stat] = 6;
395
+ if (attacker.boosts[stat] < -6)
396
+ attacker.boosts[stat] = -6;
397
+ attacker.stats[stat] = (0, util_2.getModifiedStat)(attacker.rawStats[stat], attacker.boosts[stat]);
398
+ defender.boosts[stat] = 0;
399
+ defender.stats[stat] = defender.rawStats[stat];
400
+ }
401
+ }
402
+ }
403
+ if (move.hits > 1) {
404
+ desc.hits = move.hits;
405
+ }
406
+ var turnOrder = attacker.stats.spe > defender.stats.spe ? 'first' : 'last';
407
+ var basePower = calculateBasePowerSMSSSV(gen, attacker, defender, move, field, hasAteAbilityTypeChange, desc);
408
+ if (basePower === 0) {
409
+ return result;
410
+ }
411
+ var attack = calculateAttackSMSSSV(gen, attacker, defender, move, field, desc, isCritical);
412
+ var attackStat = move.named('Shell Side Arm') &&
413
+ (0, util_2.getShellSideArmCategory)(attacker, defender) === 'Physical'
414
+ ? 'atk'
415
+ : move.named('Body Press')
416
+ ? 'def'
417
+ : move.category === 'Special'
418
+ ? 'spa'
419
+ : 'atk';
420
+ var defense = calculateDefenseSMSSSV(gen, attacker, defender, move, field, desc, isCritical);
421
+ var hitsPhysical = move.overrideDefensiveStat === 'def' || move.category === 'Physical' ||
422
+ (move.named('Shell Side Arm') && (0, util_2.getShellSideArmCategory)(attacker, defender) === 'Physical');
423
+ var defenseStat = hitsPhysical ? 'def' : 'spd';
424
+ var baseDamage = calculateBaseDamageSMSSSV(gen, attacker, defender, basePower, attack, defense, move, field, desc, isCritical);
425
+ if (hasTerrainSeed(defender) &&
426
+ field.hasTerrain(defender.item.substring(0, defender.item.indexOf(' '))) &&
427
+ items_1.SEED_BOOSTED_STAT[defender.item] === defenseStat) {
428
+ desc.defenderItem = defender.item;
429
+ }
430
+ var preStellarStabMod = (0, util_2.getStabMod)(attacker, move, desc);
431
+ var stabMod = (0, util_2.getStellarStabMod)(attacker, move, preStellarStabMod);
432
+ var applyBurn = attacker.hasStatus('brn') &&
433
+ move.category === 'Physical' &&
434
+ !attacker.hasAbility('Guts') &&
435
+ !move.named('Facade');
436
+ desc.isBurned = applyBurn;
437
+ var finalMods = calculateFinalModsSMSSSV(gen, attacker, defender, move, field, desc, isCritical, typeEffectiveness);
438
+ var protect = false;
439
+ if (field.defenderSide.isProtected &&
440
+ (attacker.isDynamaxed || (move.isZ && attacker.item && attacker.item.includes(' Z')))) {
441
+ protect = true;
442
+ desc.isProtected = true;
443
+ }
444
+ var finalMod = (0, util_2.chainMods)(finalMods, 41, 131072);
445
+ var isSpread = field.gameType !== 'Singles' &&
446
+ ['allAdjacent', 'allAdjacentFoes'].includes(move.target);
447
+ var childDamage;
448
+ if (attacker.hasAbility('Parental Bond') && move.hits === 1 && !isSpread) {
449
+ var child = attacker.clone();
450
+ child.ability = 'Parental Bond (Child)';
451
+ (0, util_2.checkMultihitBoost)(gen, child, defender, move, field, desc);
452
+ childDamage = calculateSMSSSV(gen, child, defender, move, field).damage;
453
+ desc.attackerAbility = attacker.ability;
454
+ }
455
+ var damage = [];
456
+ for (var i = 0; i < 16; i++) {
457
+ damage[i] =
458
+ (0, util_2.getFinalDamage)(baseDamage, i, typeEffectiveness, applyBurn, stabMod, finalMod, protect);
459
+ }
460
+ desc.attackBoost =
461
+ move.named('Foul Play') ? defender.boosts[attackStat] : attacker.boosts[attackStat];
462
+ if ((move.dropsStats && move.timesUsed > 1) || move.hits > 1) {
463
+ var origDefBoost = desc.defenseBoost;
464
+ var origAtkBoost = desc.attackBoost;
465
+ var numAttacks = 1;
466
+ if (move.dropsStats && move.timesUsed > 1) {
467
+ desc.moveTurns = "over ".concat(move.timesUsed, " turns");
468
+ numAttacks = move.timesUsed;
469
+ }
470
+ else {
471
+ numAttacks = move.hits;
472
+ }
473
+ var usedItems = [false, false];
474
+ var _loop_1 = function (times) {
475
+ usedItems = (0, util_2.checkMultihitBoost)(gen, attacker, defender, move, field, desc, usedItems[0], usedItems[1]);
476
+ var newAttack = calculateAttackSMSSSV(gen, attacker, defender, move, field, desc, isCritical);
477
+ var newDefense = calculateDefenseSMSSSV(gen, attacker, defender, move, field, desc, isCritical);
478
+ hasAteAbilityTypeChange = hasAteAbilityTypeChange &&
479
+ attacker.hasAbility('Aerilate', 'Galvanize', 'Pixilate', 'Refrigerate', 'Normalize');
480
+ if ((move.dropsStats && move.timesUsed > 1)) {
481
+ preStellarStabMod = (0, util_2.getStabMod)(attacker, move, desc);
482
+ typeEffectiveness = turn2typeEffectiveness;
483
+ stabMod = (0, util_2.getStellarStabMod)(attacker, move, preStellarStabMod, times);
484
+ }
485
+ var newBasePower = calculateBasePowerSMSSSV(gen, attacker, defender, move, field, hasAteAbilityTypeChange, desc, times + 1);
486
+ var newBaseDamage = calculateBaseDamageSMSSSV(gen, attacker, defender, newBasePower, newAttack, newDefense, move, field, desc, isCritical);
487
+ var newFinalMods = calculateFinalModsSMSSSV(gen, attacker, defender, move, field, desc, isCritical, typeEffectiveness, times);
488
+ var newFinalMod = (0, util_2.chainMods)(newFinalMods, 41, 131072);
489
+ var damageMultiplier = 0;
490
+ damage = damage.map(function (affectedAmount) {
491
+ var newFinalDamage = (0, util_2.getFinalDamage)(newBaseDamage, damageMultiplier, typeEffectiveness, applyBurn, stabMod, newFinalMod, protect);
492
+ damageMultiplier++;
493
+ return affectedAmount + newFinalDamage;
494
+ });
495
+ };
496
+ for (var times = 1; times < numAttacks; times++) {
497
+ _loop_1(times);
498
+ }
499
+ desc.defenseBoost = origDefBoost;
500
+ desc.attackBoost = origAtkBoost;
501
+ }
502
+ result.damage = childDamage ? [damage, childDamage] : damage;
503
+ return result;
504
+ }
505
+ exports.calculateSMSSSV = calculateSMSSSV;
506
+ function calculateBasePowerSMSSSV(gen, attacker, defender, move, field, hasAteAbilityTypeChange, desc, hit) {
507
+ var _a;
508
+ if (hit === void 0) { hit = 1; }
509
+ var turnOrder = attacker.stats.spe > defender.stats.spe ? 'first' : 'last';
510
+ var basePower;
511
+ switch (move.name) {
512
+ case 'Payback':
513
+ basePower = move.bp * (turnOrder === 'last' ? 2 : 1);
514
+ desc.moveBP = basePower;
515
+ break;
516
+ case 'Bolt Beak':
517
+ case 'Fishious Rend':
518
+ basePower = move.bp * (turnOrder !== 'last' ? 2 : 1);
519
+ desc.moveBP = basePower;
520
+ break;
521
+ case 'Pursuit':
522
+ var switching = field.defenderSide.isSwitching === 'out';
523
+ basePower = move.bp * (switching ? 2 : 1);
524
+ if (switching)
525
+ desc.isSwitching = 'out';
526
+ desc.moveBP = basePower;
527
+ break;
528
+ case 'Electro Ball':
529
+ var r = Math.floor(attacker.stats.spe / defender.stats.spe);
530
+ basePower = r >= 4 ? 150 : r >= 3 ? 120 : r >= 2 ? 80 : r >= 1 ? 60 : 40;
531
+ if (defender.stats.spe === 0)
532
+ basePower = 40;
533
+ desc.moveBP = basePower;
534
+ break;
535
+ case 'Gyro Ball':
536
+ basePower = Math.min(150, Math.floor((25 * defender.stats.spe) / attacker.stats.spe) + 1);
537
+ if (attacker.stats.spe === 0)
538
+ basePower = 1;
539
+ desc.moveBP = basePower;
540
+ break;
541
+ case 'Punishment':
542
+ basePower = Math.min(200, 60 + 20 * (0, util_2.countBoosts)(gen, defender.boosts));
543
+ desc.moveBP = basePower;
544
+ break;
545
+ case 'Low Kick':
546
+ case 'Grass Knot':
547
+ var w = (0, util_2.getWeight)(defender, desc, 'defender');
548
+ basePower = w >= 200 ? 120 : w >= 100 ? 100 : w >= 50 ? 80 : w >= 25 ? 60 : w >= 10 ? 40 : 20;
549
+ desc.moveBP = basePower;
550
+ break;
551
+ case 'Hex':
552
+ case 'Infernal Parade':
553
+ basePower = move.bp * (defender.status || defender.hasAbility('Comatose') ? 2 : 1);
554
+ desc.moveBP = basePower;
555
+ break;
556
+ case 'Barb Barrage':
557
+ basePower = move.bp * (defender.hasStatus('psn', 'tox') ? 2 : 1);
558
+ desc.moveBP = basePower;
559
+ break;
560
+ case 'Heavy Slam':
561
+ case 'Heat Crash':
562
+ var wr = (0, util_2.getWeight)(attacker, desc, 'attacker') /
563
+ (0, util_2.getWeight)(defender, desc, 'defender');
564
+ basePower = wr >= 5 ? 120 : wr >= 4 ? 100 : wr >= 3 ? 80 : wr >= 2 ? 60 : 40;
565
+ desc.moveBP = basePower;
566
+ break;
567
+ case 'Stored Power':
568
+ case 'Power Trip':
569
+ basePower = 20 + 20 * (0, util_2.countBoosts)(gen, attacker.boosts);
570
+ desc.moveBP = basePower;
571
+ break;
572
+ case 'Acrobatics':
573
+ basePower = move.bp * (attacker.hasItem('Flying Gem') ||
574
+ (!attacker.item || (0, util_2.isQPActive)(attacker, field)) ? 2 : 1);
575
+ desc.moveBP = basePower;
576
+ break;
577
+ case 'Assurance':
578
+ basePower = move.bp * (defender.hasAbility('Parental Bond (Child)') ? 2 : 1);
579
+ break;
580
+ case 'Wake-Up Slap':
581
+ basePower = move.bp * (defender.hasStatus('slp') || defender.hasAbility('Comatose') ? 2 : 1);
582
+ desc.moveBP = basePower;
583
+ break;
584
+ case 'Smelling Salts':
585
+ basePower = move.bp * (defender.hasStatus('par') ? 2 : 1);
586
+ desc.moveBP = basePower;
587
+ break;
588
+ case 'Weather Ball':
589
+ basePower = move.bp * (field.weather && !field.hasWeather('Strong Winds') ? 2 : 1);
590
+ if (field.hasWeather('Sun', 'Harsh Sunshine', 'Rain', 'Heavy Rain') &&
591
+ attacker.hasItem('Utility Umbrella'))
592
+ basePower = move.bp;
593
+ desc.moveBP = basePower;
594
+ break;
595
+ case 'Terrain Pulse':
596
+ basePower = move.bp * ((0, util_2.isGrounded)(attacker, field) && field.terrain ? 2 : 1);
597
+ desc.moveBP = basePower;
598
+ break;
599
+ case 'Rising Voltage':
600
+ basePower = move.bp * (((0, util_2.isGrounded)(defender, field) && field.hasTerrain('Electric')) ? 2 : 1);
601
+ desc.moveBP = basePower;
602
+ break;
603
+ case 'Psyblade':
604
+ basePower = move.bp * (field.hasTerrain('Electric') ? 1.5 : 1);
605
+ if (field.hasTerrain('Electric')) {
606
+ desc.moveBP = basePower;
607
+ desc.terrain = field.terrain;
608
+ }
609
+ break;
610
+ case 'Fling':
611
+ basePower = (0, items_1.getFlingPower)(attacker.item);
612
+ desc.moveBP = basePower;
613
+ desc.attackerItem = attacker.item;
614
+ break;
615
+ case 'Dragon Energy':
616
+ case 'Eruption':
617
+ case 'Water Spout':
618
+ basePower = Math.max(1, Math.floor((150 * attacker.curHP()) / attacker.maxHP()));
619
+ desc.moveBP = basePower;
620
+ break;
621
+ case 'Flail':
622
+ case 'Reversal':
623
+ var p = Math.floor((48 * attacker.curHP()) / attacker.maxHP());
624
+ basePower = p <= 1 ? 200 : p <= 4 ? 150 : p <= 9 ? 100 : p <= 16 ? 80 : p <= 32 ? 40 : 20;
625
+ desc.moveBP = basePower;
626
+ break;
627
+ case 'Natural Gift':
628
+ if ((_a = attacker.item) === null || _a === void 0 ? void 0 : _a.endsWith('Berry')) {
629
+ var gift = (0, items_1.getNaturalGift)(gen, attacker.item);
630
+ basePower = gift.p;
631
+ desc.attackerItem = attacker.item;
632
+ desc.moveBP = move.bp;
633
+ }
634
+ else {
635
+ basePower = move.bp;
636
+ }
637
+ break;
638
+ case 'Nature Power':
639
+ move.category = 'Special';
640
+ move.secondaries = true;
641
+ if (attacker.hasAbility('Prankster') && defender.types.includes('Dark')) {
642
+ basePower = 0;
643
+ desc.moveName = 'Nature Power';
644
+ desc.attackerAbility = 'Prankster';
645
+ break;
646
+ }
647
+ switch (field.terrain) {
648
+ case 'Electric':
649
+ basePower = 90;
650
+ desc.moveName = 'Thunderbolt';
651
+ break;
652
+ case 'Grassy':
653
+ basePower = 90;
654
+ desc.moveName = 'Energy Ball';
655
+ break;
656
+ case 'Misty':
657
+ basePower = 95;
658
+ desc.moveName = 'Moonblast';
659
+ break;
660
+ case 'Psychic':
661
+ if (attacker.hasAbility('Prankster') && (0, util_2.isGrounded)(defender, field)) {
662
+ basePower = 0;
663
+ desc.attackerAbility = 'Prankster';
664
+ }
665
+ else {
666
+ basePower = 90;
667
+ desc.moveName = 'Psychic';
668
+ }
669
+ break;
670
+ default:
671
+ basePower = 80;
672
+ desc.moveName = 'Tri Attack';
673
+ }
674
+ break;
675
+ case 'Water Shuriken':
676
+ basePower = attacker.named('Greninja-Ash') && attacker.hasAbility('Battle Bond') ? 20 : 15;
677
+ desc.moveBP = basePower;
678
+ break;
679
+ case 'Triple Axel':
680
+ basePower = hit * 20;
681
+ desc.moveBP = move.hits === 2 ? 60 : move.hits === 3 ? 120 : 20;
682
+ break;
683
+ case 'Triple Kick':
684
+ basePower = hit * 10;
685
+ desc.moveBP = move.hits === 2 ? 30 : move.hits === 3 ? 60 : 10;
686
+ break;
687
+ case 'Crush Grip':
688
+ case 'Wring Out':
689
+ basePower = 100 * Math.floor((defender.curHP() * 4096) / defender.maxHP());
690
+ basePower = Math.floor(Math.floor((120 * basePower + 2048 - 1) / 4096) / 100) || 1;
691
+ desc.moveBP = basePower;
692
+ break;
693
+ case 'Hard Press':
694
+ basePower = 100 * Math.floor((defender.curHP() * 4096) / defender.maxHP());
695
+ basePower = Math.floor(Math.floor((100 * basePower + 2048 - 1) / 4096) / 100) || 1;
696
+ desc.moveBP = basePower;
697
+ break;
698
+ case 'Tera Blast':
699
+ basePower = attacker.teraType === 'Stellar' ? 100 : 80;
700
+ desc.moveBP = basePower;
701
+ break;
702
+ default:
703
+ basePower = move.bp;
704
+ }
705
+ if (basePower === 0) {
706
+ return 0;
707
+ }
708
+ if (move.named('Breakneck Blitz', 'Bloom Doom', 'Inferno Overdrive', 'Hydro Vortex', 'Gigavolt Havoc', 'Subzero Slammer', 'Supersonic Skystrike', 'Savage Spin-Out', 'Acid Downpour', 'Tectonic Rage', 'Continental Crush', 'All-Out Pummeling', 'Shattered Psyche', 'Never-Ending Nightmare', 'Devastating Drake', 'Black Hole Eclipse', 'Corkscrew Crash', 'Twinkle Tackle') || move.isMax) {
709
+ desc.moveBP = move.bp;
710
+ }
711
+ var bpMods = calculateBPModsSMSSSV(gen, attacker, defender, move, field, desc, basePower, hasAteAbilityTypeChange, turnOrder);
712
+ basePower = (0, util_2.OF16)(Math.max(1, (0, util_2.pokeRound)((basePower * (0, util_2.chainMods)(bpMods, 41, 2097152)) / 4096)));
713
+ if (attacker.teraType && move.type === attacker.teraType &&
714
+ attacker.hasType(attacker.teraType) && move.hits === 1 && !move.multiaccuracy &&
715
+ move.priority <= 0 && move.bp > 0 && !move.named('Dragon Energy', 'Eruption', 'Water Spout') &&
716
+ basePower < 60 && gen.num >= 9) {
717
+ basePower = 60;
718
+ desc.moveBP = 60;
719
+ }
720
+ return basePower;
721
+ }
722
+ exports.calculateBasePowerSMSSSV = calculateBasePowerSMSSSV;
723
+ function calculateBPModsSMSSSV(gen, attacker, defender, move, field, desc, basePower, hasAteAbilityTypeChange, turnOrder) {
724
+ var bpMods = [];
725
+ var defenderItem = (defender.item && defender.item !== '')
726
+ ? defender.item : defender.disabledItem;
727
+ var resistedKnockOffDamage = (!defenderItem || (0, util_2.isQPActive)(defender, field)) ||
728
+ (defender.named('Dialga-Origin') && defenderItem === 'Adamant Crystal') ||
729
+ (defender.named('Palkia-Origin') && defenderItem === 'Lustrous Globe') ||
730
+ (defender.name.includes('Giratina-Origin') && defenderItem.includes('Griseous')) ||
731
+ (defender.name.includes('Arceus') && defenderItem.includes('Plate')) ||
732
+ (defender.name.includes('Genesect') && defenderItem.includes('Drive')) ||
733
+ (defender.named('Groudon', 'Groudon-Primal') && defenderItem === 'Red Orb') ||
734
+ (defender.named('Kyogre', 'Kyogre-Primal') && defenderItem === 'Blue Orb') ||
735
+ (defender.name.includes('Silvally') && defenderItem.includes('Memory')) ||
736
+ defenderItem.includes(' Z') ||
737
+ (defender.named('Zacian') && defenderItem === 'Rusted Sword') ||
738
+ (defender.named('Zamazenta') && defenderItem === 'Rusted Shield') ||
739
+ (defender.name.includes('Ogerpon-Cornerstone') && defenderItem === 'Cornerstone Mask') ||
740
+ (defender.name.includes('Ogerpon-Hearthflame') && defenderItem === 'Hearthflame Mask') ||
741
+ (defender.name.includes('Ogerpon-Wellspring') && defenderItem === 'Wellspring Mask') ||
742
+ (defender.named('Venomicon-Epilogue') && defenderItem === 'Vile Vial');
743
+ if (!resistedKnockOffDamage && defenderItem) {
744
+ var item = gen.items.get((0, util_1.toID)(defenderItem));
745
+ resistedKnockOffDamage = !!item.megaEvolves && defender.name.includes(item.megaEvolves);
746
+ }
747
+ if ((move.named('Facade') && attacker.hasStatus('brn', 'par', 'psn', 'tox')) ||
748
+ (move.named('Brine') && defender.curHP() <= defender.maxHP() / 2) ||
749
+ (move.named('Venoshock') && defender.hasStatus('psn', 'tox')) ||
750
+ (move.named('Lash Out') && ((0, util_2.countBoosts)(gen, attacker.boosts) < 0))) {
751
+ bpMods.push(8192);
752
+ desc.moveBP = basePower * 2;
753
+ }
754
+ else if (move.named('Expanding Force') && (0, util_2.isGrounded)(attacker, field) && field.hasTerrain('Psychic')) {
755
+ move.target = 'allAdjacentFoes';
756
+ bpMods.push(6144);
757
+ desc.moveBP = basePower * 1.5;
758
+ }
759
+ else if ((move.named('Knock Off') && !resistedKnockOffDamage) ||
760
+ (move.named('Misty Explosion') && (0, util_2.isGrounded)(attacker, field) && field.hasTerrain('Misty')) ||
761
+ (move.named('Grav Apple') && field.isGravity)) {
762
+ bpMods.push(6144);
763
+ desc.moveBP = basePower * 1.5;
764
+ }
765
+ else if (move.named('Solar Beam', 'Solar Blade') &&
766
+ field.hasWeather('Rain', 'Heavy Rain', 'Sand', 'Hail', 'Snow')) {
767
+ bpMods.push(2048);
768
+ desc.moveBP = basePower / 2;
769
+ desc.weather = field.weather;
770
+ }
771
+ else if (move.named('Collision Course', 'Electro Drift')) {
772
+ var isGhostRevealed = attacker.hasAbility('Scrappy') || attacker.hasAbility('Mind\'s Eye') ||
773
+ field.defenderSide.isForesight;
774
+ var isRingTarget = defender.hasItem('Ring Target') && !defender.hasAbility('Klutz');
775
+ var types = defender.teraType && defender.teraType !== 'Stellar'
776
+ ? [defender.teraType] : defender.types;
777
+ var type1Effectiveness = (0, util_2.getMoveEffectiveness)(gen, move, types[0], isGhostRevealed, field.isGravity, isRingTarget);
778
+ var type2Effectiveness = types[1] ? (0, util_2.getMoveEffectiveness)(gen, move, types[1], isGhostRevealed, field.isGravity, isRingTarget) : 1;
779
+ if (type1Effectiveness * type2Effectiveness >= 2) {
780
+ bpMods.push(5461);
781
+ desc.moveBP = basePower * (5461 / 4096);
782
+ }
783
+ }
784
+ if (field.attackerSide.isHelpingHand) {
785
+ bpMods.push(6144);
786
+ desc.isHelpingHand = true;
787
+ }
788
+ var terrainMultiplier = gen.num > 7 ? 5325 : 6144;
789
+ if ((0, util_2.isGrounded)(attacker, field)) {
790
+ if ((field.hasTerrain('Electric') && move.hasType('Electric')) ||
791
+ (field.hasTerrain('Grassy') && move.hasType('Grass')) ||
792
+ (field.hasTerrain('Psychic') && move.hasType('Psychic'))) {
793
+ bpMods.push(terrainMultiplier);
794
+ desc.terrain = field.terrain;
795
+ }
796
+ }
797
+ if ((0, util_2.isGrounded)(defender, field)) {
798
+ if ((field.hasTerrain('Misty') && move.hasType('Dragon')) ||
799
+ (field.hasTerrain('Grassy') && move.named('Bulldoze', 'Earthquake'))) {
800
+ bpMods.push(2048);
801
+ desc.terrain = field.terrain;
802
+ }
803
+ }
804
+ if ((attacker.hasAbility('Technician') && basePower <= 60) ||
805
+ (attacker.hasAbility('Flare Boost') &&
806
+ attacker.hasStatus('brn') && move.category === 'Special') ||
807
+ (attacker.hasAbility('Toxic Boost') &&
808
+ attacker.hasStatus('psn', 'tox') && move.category === 'Physical') ||
809
+ (attacker.hasAbility('Mega Launcher') && move.flags.pulse) ||
810
+ (attacker.hasAbility('Strong Jaw') && move.flags.bite) ||
811
+ (attacker.hasAbility('Steely Spirit') && move.hasType('Steel')) ||
812
+ (attacker.hasAbility('Sharpness') && move.flags.slicing)) {
813
+ bpMods.push(6144);
814
+ desc.attackerAbility = attacker.ability;
815
+ }
816
+ var aura = "".concat(move.type, " Aura");
817
+ var isAttackerAura = attacker.hasAbility(aura);
818
+ var isDefenderAura = defender.hasAbility(aura);
819
+ var isUserAuraBreak = attacker.hasAbility('Aura Break') || defender.hasAbility('Aura Break');
820
+ var isFieldAuraBreak = field.isAuraBreak;
821
+ var isFieldFairyAura = field.isFairyAura && move.type === 'Fairy';
822
+ var isFieldDarkAura = field.isDarkAura && move.type === 'Dark';
823
+ var auraActive = isAttackerAura || isDefenderAura || isFieldFairyAura || isFieldDarkAura;
824
+ var auraBreak = isFieldAuraBreak || isUserAuraBreak;
825
+ if (auraActive) {
826
+ if (auraBreak) {
827
+ bpMods.push(3072);
828
+ desc.attackerAbility = attacker.ability;
829
+ desc.defenderAbility = defender.ability;
830
+ }
831
+ else {
832
+ bpMods.push(5448);
833
+ if (isAttackerAura)
834
+ desc.attackerAbility = attacker.ability;
835
+ if (isDefenderAura)
836
+ desc.defenderAbility = defender.ability;
837
+ }
838
+ }
839
+ if ((attacker.hasAbility('Sheer Force') &&
840
+ (move.secondaries || move.named('Order Up')) && !move.isMax) ||
841
+ (attacker.hasAbility('Sand Force') &&
842
+ field.hasWeather('Sand') && move.hasType('Rock', 'Ground', 'Steel')) ||
843
+ (attacker.hasAbility('Analytic') &&
844
+ (turnOrder !== 'first' || field.defenderSide.isSwitching === 'out')) ||
845
+ (attacker.hasAbility('Tough Claws') && move.flags.contact) ||
846
+ (attacker.hasAbility('Punk Rock') && move.flags.sound)) {
847
+ bpMods.push(5325);
848
+ desc.attackerAbility = attacker.ability;
849
+ }
850
+ if (field.attackerSide.isBattery && move.category === 'Special') {
851
+ bpMods.push(5325);
852
+ desc.isBattery = true;
853
+ }
854
+ if (field.attackerSide.isPowerSpot) {
855
+ bpMods.push(5325);
856
+ desc.isPowerSpot = true;
857
+ }
858
+ if (attacker.hasAbility('Rivalry') && ![attacker.gender, defender.gender].includes('N')) {
859
+ if (attacker.gender === defender.gender) {
860
+ bpMods.push(5120);
861
+ desc.rivalry = 'buffed';
862
+ }
863
+ else {
864
+ bpMods.push(3072);
865
+ desc.rivalry = 'nerfed';
866
+ }
867
+ desc.attackerAbility = attacker.ability;
868
+ }
869
+ if (!move.isMax && hasAteAbilityTypeChange) {
870
+ bpMods.push(4915);
871
+ }
872
+ if ((attacker.hasAbility('Reckless') && (move.recoil || move.hasCrashDamage)) ||
873
+ (attacker.hasAbility('Iron Fist') && move.flags.punch)) {
874
+ bpMods.push(4915);
875
+ desc.attackerAbility = attacker.ability;
876
+ }
877
+ if (gen.num <= 8 && defender.hasAbility('Heatproof') && move.hasType('Fire')) {
878
+ bpMods.push(2048);
879
+ desc.defenderAbility = defender.ability;
880
+ }
881
+ else if (defender.hasAbility('Dry Skin') && move.hasType('Fire')) {
882
+ bpMods.push(5120);
883
+ desc.defenderAbility = defender.ability;
884
+ }
885
+ if (attacker.hasAbility('Supreme Overlord') && attacker.alliesFainted) {
886
+ var powMod = [4096, 4506, 4915, 5325, 5734, 6144];
887
+ bpMods.push(powMod[Math.min(5, attacker.alliesFainted)]);
888
+ desc.attackerAbility = attacker.ability;
889
+ desc.alliesFainted = attacker.alliesFainted;
890
+ }
891
+ if (attacker.hasItem("".concat(move.type, " Gem"))) {
892
+ bpMods.push(5325);
893
+ desc.attackerItem = attacker.item;
894
+ }
895
+ else if ((((attacker.hasItem('Adamant Crystal') && attacker.named('Dialga-Origin')) ||
896
+ (attacker.hasItem('Adamant Orb') && attacker.named('Dialga'))) &&
897
+ move.hasType('Steel', 'Dragon')) ||
898
+ (((attacker.hasItem('Lustrous Orb') &&
899
+ attacker.named('Palkia')) ||
900
+ (attacker.hasItem('Lustrous Globe') && attacker.named('Palkia-Origin'))) &&
901
+ move.hasType('Water', 'Dragon')) ||
902
+ (((attacker.hasItem('Griseous Orb') || attacker.hasItem('Griseous Core')) &&
903
+ (attacker.named('Giratina-Origin') || attacker.named('Giratina'))) &&
904
+ move.hasType('Ghost', 'Dragon')) ||
905
+ (attacker.hasItem('Vile Vial') &&
906
+ attacker.named('Venomicon-Epilogue') &&
907
+ move.hasType('Poison', 'Flying')) ||
908
+ (attacker.hasItem('Soul Dew') &&
909
+ attacker.named('Latios', 'Latias', 'Latios-Mega', 'Latias-Mega') &&
910
+ move.hasType('Psychic', 'Dragon')) ||
911
+ attacker.item && move.hasType((0, items_1.getItemBoostType)(attacker.item)) ||
912
+ (attacker.name.includes('Ogerpon-Cornerstone') && attacker.hasItem('Cornerstone Mask')) ||
913
+ (attacker.name.includes('Ogerpon-Hearthflame') && attacker.hasItem('Hearthflame Mask')) ||
914
+ (attacker.name.includes('Ogerpon-Wellspring') && attacker.hasItem('Wellspring Mask'))) {
915
+ bpMods.push(4915);
916
+ desc.attackerItem = attacker.item;
917
+ }
918
+ else if ((attacker.hasItem('Muscle Band') && move.category === 'Physical') ||
919
+ (attacker.hasItem('Wise Glasses') && move.category === 'Special')) {
920
+ bpMods.push(4505);
921
+ desc.attackerItem = attacker.item;
922
+ }
923
+ else if (attacker.hasItem('Punching Glove') && move.flags.punch) {
924
+ bpMods.push(4506);
925
+ }
926
+ return bpMods;
927
+ }
928
+ exports.calculateBPModsSMSSSV = calculateBPModsSMSSSV;
929
+ function calculateAttackSMSSSV(gen, attacker, defender, move, field, desc, isCritical) {
930
+ if (isCritical === void 0) { isCritical = false; }
931
+ var attack;
932
+ var attackStat = move.named('Shell Side Arm') &&
933
+ (0, util_2.getShellSideArmCategory)(attacker, defender) === 'Physical'
934
+ ? 'atk'
935
+ : move.named('Body Press')
936
+ ? 'def'
937
+ : move.category === 'Special'
938
+ ? 'spa'
939
+ : 'atk';
940
+ desc.attackEVs =
941
+ move.named('Foul Play')
942
+ ? (0, util_2.getStatDescriptionText)(gen, defender, attackStat, defender.nature)
943
+ : (0, util_2.getStatDescriptionText)(gen, attacker, attackStat, attacker.nature);
944
+ var attackSource = move.named('Foul Play') ? defender : attacker;
945
+ if (attackSource.boosts[attackStat] === 0 ||
946
+ (isCritical && attackSource.boosts[attackStat] < 0)) {
947
+ attack = attackSource.rawStats[attackStat];
948
+ }
949
+ else if (defender.hasAbility('Unaware')) {
950
+ attack = attackSource.rawStats[attackStat];
951
+ desc.defenderAbility = defender.ability;
952
+ }
953
+ else {
954
+ attack = (0, util_2.getModifiedStat)(attackSource.rawStats[attackStat], attackSource.boosts[attackStat]);
955
+ desc.attackBoost = attackSource.boosts[attackStat];
956
+ }
957
+ if (attacker.hasAbility('Hustle') && move.category === 'Physical') {
958
+ attack = (0, util_2.pokeRound)((attack * 3) / 2);
959
+ desc.attackerAbility = attacker.ability;
960
+ }
961
+ var atMods = calculateAtModsSMSSSV(gen, attacker, defender, move, field, desc);
962
+ attack = (0, util_2.OF16)(Math.max(1, (0, util_2.pokeRound)((attack * (0, util_2.chainMods)(atMods, 410, 131072)) / 4096)));
963
+ return attack;
964
+ }
965
+ exports.calculateAttackSMSSSV = calculateAttackSMSSSV;
966
+ function calculateAtModsSMSSSV(gen, attacker, defender, move, field, desc) {
967
+ var atMods = [];
968
+ if ((attacker.hasAbility('Slow Start') && attacker.abilityOn &&
969
+ (move.category === 'Physical' || (move.category === 'Special' && move.isZ))) ||
970
+ (attacker.hasAbility('Defeatist') && attacker.curHP() <= attacker.maxHP() / 2)) {
971
+ atMods.push(2048);
972
+ desc.attackerAbility = attacker.ability;
973
+ }
974
+ else if ((attacker.hasAbility('Solar Power') &&
975
+ field.hasWeather('Sun', 'Harsh Sunshine') &&
976
+ move.category === 'Special') ||
977
+ (attacker.named('Cherrim') &&
978
+ attacker.hasAbility('Flower Gift') &&
979
+ field.hasWeather('Sun', 'Harsh Sunshine') &&
980
+ move.category === 'Physical')) {
981
+ atMods.push(6144);
982
+ desc.attackerAbility = attacker.ability;
983
+ desc.weather = field.weather;
984
+ }
985
+ else if ((attacker.hasAbility('Gorilla Tactics') && move.category === 'Physical' &&
986
+ !attacker.isDynamaxed)) {
987
+ atMods.push(6144);
988
+ desc.attackerAbility = attacker.ability;
989
+ }
990
+ else if ((attacker.hasAbility('Guts') && attacker.status && move.category === 'Physical') ||
991
+ (attacker.curHP() <= attacker.maxHP() / 3 &&
992
+ ((attacker.hasAbility('Overgrow') && move.hasType('Grass')) ||
993
+ (attacker.hasAbility('Blaze') && move.hasType('Fire')) ||
994
+ (attacker.hasAbility('Torrent') && move.hasType('Water')) ||
995
+ (attacker.hasAbility('Swarm') && move.hasType('Bug')))) ||
996
+ (move.category === 'Special' && attacker.abilityOn && attacker.hasAbility('Plus', 'Minus'))) {
997
+ atMods.push(6144);
998
+ desc.attackerAbility = attacker.ability;
999
+ }
1000
+ else if (attacker.hasAbility('Flash Fire') && attacker.abilityOn && move.hasType('Fire')) {
1001
+ atMods.push(6144);
1002
+ desc.attackerAbility = 'Flash Fire';
1003
+ }
1004
+ else if ((attacker.hasAbility('Steelworker') && move.hasType('Steel')) ||
1005
+ (attacker.hasAbility('Dragon\'s Maw') && move.hasType('Dragon')) ||
1006
+ (attacker.hasAbility('Rocky Payload') && move.hasType('Rock'))) {
1007
+ atMods.push(6144);
1008
+ desc.attackerAbility = attacker.ability;
1009
+ }
1010
+ else if (attacker.hasAbility('Transistor') && move.hasType('Electric')) {
1011
+ atMods.push(gen.num >= 9 ? 5325 : 6144);
1012
+ desc.attackerAbility = attacker.ability;
1013
+ }
1014
+ else if (attacker.hasAbility('Stakeout') && attacker.abilityOn) {
1015
+ atMods.push(8192);
1016
+ desc.attackerAbility = attacker.ability;
1017
+ }
1018
+ else if ((attacker.hasAbility('Water Bubble') && move.hasType('Water')) ||
1019
+ (attacker.hasAbility('Huge Power', 'Pure Power') && move.category === 'Physical')) {
1020
+ atMods.push(8192);
1021
+ desc.attackerAbility = attacker.ability;
1022
+ }
1023
+ if (field.attackerSide.isFlowerGift &&
1024
+ !attacker.hasAbility('Flower Gift') &&
1025
+ field.hasWeather('Sun', 'Harsh Sunshine') &&
1026
+ move.category === 'Physical') {
1027
+ atMods.push(6144);
1028
+ desc.weather = field.weather;
1029
+ desc.isFlowerGiftAttacker = true;
1030
+ }
1031
+ if (field.attackerSide.isSteelySpirit &&
1032
+ move.hasType('Steel')) {
1033
+ atMods.push(6144);
1034
+ desc.isSteelySpiritAttacker = true;
1035
+ }
1036
+ if ((defender.hasAbility('Thick Fat') && move.hasType('Fire', 'Ice')) ||
1037
+ (defender.hasAbility('Water Bubble') && move.hasType('Fire')) ||
1038
+ (defender.hasAbility('Purifying Salt') && move.hasType('Ghost'))) {
1039
+ atMods.push(2048);
1040
+ desc.defenderAbility = defender.ability;
1041
+ }
1042
+ if (gen.num >= 9 && defender.hasAbility('Heatproof') && move.hasType('Fire')) {
1043
+ atMods.push(2048);
1044
+ desc.defenderAbility = defender.ability;
1045
+ }
1046
+ var isTabletsOfRuinActive = (defender.hasAbility('Tablets of Ruin') || field.isTabletsOfRuin) &&
1047
+ !attacker.hasAbility('Tablets of Ruin');
1048
+ var isVesselOfRuinActive = (defender.hasAbility('Vessel of Ruin') || field.isVesselOfRuin) &&
1049
+ !attacker.hasAbility('Vessel of Ruin');
1050
+ if ((isTabletsOfRuinActive && move.category === 'Physical') ||
1051
+ (isVesselOfRuinActive && move.category === 'Special')) {
1052
+ if (defender.hasAbility('Tablets of Ruin') || defender.hasAbility('Vessel of Ruin')) {
1053
+ desc.defenderAbility = defender.ability;
1054
+ }
1055
+ else {
1056
+ desc[move.category === 'Special' ? 'isVesselOfRuin' : 'isTabletsOfRuin'] = true;
1057
+ }
1058
+ atMods.push(3072);
1059
+ }
1060
+ if ((0, util_2.isQPActive)(attacker, field)) {
1061
+ if ((move.category === 'Physical' && (0, util_2.getQPBoostedStat)(attacker) === 'atk') ||
1062
+ (move.category === 'Special' && (0, util_2.getQPBoostedStat)(attacker) === 'spa')) {
1063
+ atMods.push(5325);
1064
+ desc.attackerAbility = attacker.ability;
1065
+ }
1066
+ }
1067
+ if ((attacker.hasAbility('Hadron Engine') && move.category === 'Special' &&
1068
+ field.hasTerrain('Electric')) ||
1069
+ (attacker.hasAbility('Orichalcum Pulse') && move.category === 'Physical' &&
1070
+ field.hasWeather('Sun', 'Harsh Sunshine') && !attacker.hasItem('Utility Umbrella'))) {
1071
+ atMods.push(5461);
1072
+ desc.attackerAbility = attacker.ability;
1073
+ }
1074
+ if ((attacker.hasItem('Thick Club') &&
1075
+ attacker.named('Cubone', 'Marowak', 'Marowak-Alola', 'Marowak-Alola-Totem') &&
1076
+ move.category === 'Physical') ||
1077
+ (attacker.hasItem('Deep Sea Tooth') &&
1078
+ attacker.named('Clamperl') &&
1079
+ move.category === 'Special') ||
1080
+ (attacker.hasItem('Light Ball') && attacker.name.includes('Pikachu') && !move.isZ)) {
1081
+ atMods.push(8192);
1082
+ desc.attackerItem = attacker.item;
1083
+ }
1084
+ else if (!move.isZ && !move.isMax &&
1085
+ ((attacker.hasItem('Choice Band') && move.category === 'Physical') ||
1086
+ (attacker.hasItem('Choice Specs') && move.category === 'Special'))) {
1087
+ atMods.push(6144);
1088
+ desc.attackerItem = attacker.item;
1089
+ }
1090
+ return atMods;
1091
+ }
1092
+ exports.calculateAtModsSMSSSV = calculateAtModsSMSSSV;
1093
+ function calculateDefenseSMSSSV(gen, attacker, defender, move, field, desc, isCritical) {
1094
+ if (isCritical === void 0) { isCritical = false; }
1095
+ var defense;
1096
+ var hitsPhysical = move.overrideDefensiveStat === 'def' || move.category === 'Physical' ||
1097
+ (move.named('Shell Side Arm') && (0, util_2.getShellSideArmCategory)(attacker, defender) === 'Physical');
1098
+ var defenseStat = hitsPhysical ? 'def' : 'spd';
1099
+ desc.defenseEVs = (0, util_2.getStatDescriptionText)(gen, defender, defenseStat, defender.nature);
1100
+ if (defender.boosts[defenseStat] === 0 ||
1101
+ (isCritical && defender.boosts[defenseStat] > 0) ||
1102
+ move.ignoreDefensive) {
1103
+ defense = defender.rawStats[defenseStat];
1104
+ }
1105
+ else if (attacker.hasAbility('Unaware')) {
1106
+ defense = defender.rawStats[defenseStat];
1107
+ desc.attackerAbility = attacker.ability;
1108
+ }
1109
+ else {
1110
+ defense = (0, util_2.getModifiedStat)(defender.rawStats[defenseStat], defender.boosts[defenseStat]);
1111
+ desc.defenseBoost = defender.boosts[defenseStat];
1112
+ }
1113
+ if (field.hasWeather('Sand') && defender.hasType('Rock') && !hitsPhysical) {
1114
+ defense = (0, util_2.pokeRound)((defense * 3) / 2);
1115
+ desc.weather = field.weather;
1116
+ }
1117
+ if (field.hasWeather('Snow') && defender.hasType('Ice') && hitsPhysical) {
1118
+ defense = (0, util_2.pokeRound)((defense * 3) / 2);
1119
+ desc.weather = field.weather;
1120
+ }
1121
+ var dfMods = calculateDfModsSMSSSV(gen, attacker, defender, move, field, desc, isCritical, hitsPhysical);
1122
+ return (0, util_2.OF16)(Math.max(1, (0, util_2.pokeRound)((defense * (0, util_2.chainMods)(dfMods, 410, 131072)) / 4096)));
1123
+ }
1124
+ exports.calculateDefenseSMSSSV = calculateDefenseSMSSSV;
1125
+ function calculateDfModsSMSSSV(gen, attacker, defender, move, field, desc, isCritical, hitsPhysical) {
1126
+ var _a;
1127
+ if (isCritical === void 0) { isCritical = false; }
1128
+ if (hitsPhysical === void 0) { hitsPhysical = false; }
1129
+ var dfMods = [];
1130
+ if (defender.hasAbility('Marvel Scale') && defender.status && hitsPhysical) {
1131
+ dfMods.push(6144);
1132
+ desc.defenderAbility = defender.ability;
1133
+ }
1134
+ else if (defender.named('Cherrim') &&
1135
+ defender.hasAbility('Flower Gift') &&
1136
+ field.hasWeather('Sun', 'Harsh Sunshine') &&
1137
+ !hitsPhysical) {
1138
+ dfMods.push(6144);
1139
+ desc.defenderAbility = defender.ability;
1140
+ desc.weather = field.weather;
1141
+ }
1142
+ else if (field.defenderSide.isFlowerGift &&
1143
+ field.hasWeather('Sun', 'Harsh Sunshine') &&
1144
+ !hitsPhysical) {
1145
+ dfMods.push(6144);
1146
+ desc.weather = field.weather;
1147
+ desc.isFlowerGiftDefender = true;
1148
+ }
1149
+ else if (defender.hasAbility('Grass Pelt') &&
1150
+ field.hasTerrain('Grassy') &&
1151
+ hitsPhysical) {
1152
+ dfMods.push(6144);
1153
+ desc.defenderAbility = defender.ability;
1154
+ }
1155
+ else if (defender.hasAbility('Fur Coat') && hitsPhysical) {
1156
+ dfMods.push(8192);
1157
+ desc.defenderAbility = defender.ability;
1158
+ }
1159
+ var isSwordOfRuinActive = (attacker.hasAbility('Sword of Ruin') || field.isSwordOfRuin) &&
1160
+ !defender.hasAbility('Sword of Ruin');
1161
+ var isBeadsOfRuinActive = (attacker.hasAbility('Beads of Ruin') || field.isBeadsOfRuin) &&
1162
+ !defender.hasAbility('Beads of Ruin');
1163
+ if ((isSwordOfRuinActive && hitsPhysical) ||
1164
+ (isBeadsOfRuinActive && !hitsPhysical)) {
1165
+ if (attacker.hasAbility('Sword of Ruin') || attacker.hasAbility('Beads of Ruin')) {
1166
+ desc.attackerAbility = attacker.ability;
1167
+ }
1168
+ else {
1169
+ desc[hitsPhysical ? 'isSwordOfRuin' : 'isBeadsOfRuin'] = true;
1170
+ }
1171
+ dfMods.push(3072);
1172
+ }
1173
+ if ((0, util_2.isQPActive)(defender, field)) {
1174
+ if ((hitsPhysical && (0, util_2.getQPBoostedStat)(defender) === 'def') ||
1175
+ (!hitsPhysical && (0, util_2.getQPBoostedStat)(defender) === 'spd')) {
1176
+ desc.defenderAbility = defender.ability;
1177
+ dfMods.push(5324);
1178
+ }
1179
+ }
1180
+ if ((defender.hasItem('Eviolite') &&
1181
+ (defender.name === 'Dipplin' || ((_a = gen.species.get((0, util_1.toID)(defender.name))) === null || _a === void 0 ? void 0 : _a.nfe))) ||
1182
+ (!hitsPhysical && defender.hasItem('Assault Vest'))) {
1183
+ dfMods.push(6144);
1184
+ desc.defenderItem = defender.item;
1185
+ }
1186
+ else if ((defender.hasItem('Metal Powder') && defender.named('Ditto') && hitsPhysical) ||
1187
+ (defender.hasItem('Deep Sea Scale') && defender.named('Clamperl') && !hitsPhysical)) {
1188
+ dfMods.push(8192);
1189
+ desc.defenderItem = defender.item;
1190
+ }
1191
+ return dfMods;
1192
+ }
1193
+ exports.calculateDfModsSMSSSV = calculateDfModsSMSSSV;
1194
+ function calculateBaseDamageSMSSSV(gen, attacker, defender, basePower, attack, defense, move, field, desc, isCritical) {
1195
+ if (isCritical === void 0) { isCritical = false; }
1196
+ var baseDamage = (0, util_2.getBaseDamage)(attacker.level, basePower, attack, defense);
1197
+ var isSpread = field.gameType !== 'Singles' &&
1198
+ ['allAdjacent', 'allAdjacentFoes'].includes(move.target);
1199
+ if (isSpread) {
1200
+ baseDamage = (0, util_2.pokeRound)((0, util_2.OF32)(baseDamage * 3072) / 4096);
1201
+ }
1202
+ if (attacker.hasAbility('Parental Bond (Child)')) {
1203
+ baseDamage = (0, util_2.pokeRound)((0, util_2.OF32)(baseDamage * 1024) / 4096);
1204
+ }
1205
+ if (field.hasWeather('Sun') && move.named('Hydro Steam') && !attacker.hasItem('Utility Umbrella')) {
1206
+ baseDamage = (0, util_2.pokeRound)((0, util_2.OF32)(baseDamage * 6144) / 4096);
1207
+ desc.weather = field.weather;
1208
+ }
1209
+ else if (!defender.hasItem('Utility Umbrella')) {
1210
+ if ((field.hasWeather('Sun', 'Harsh Sunshine') && move.hasType('Fire')) ||
1211
+ (field.hasWeather('Rain', 'Heavy Rain') && move.hasType('Water'))) {
1212
+ baseDamage = (0, util_2.pokeRound)((0, util_2.OF32)(baseDamage * 6144) / 4096);
1213
+ desc.weather = field.weather;
1214
+ }
1215
+ else if ((field.hasWeather('Sun') && move.hasType('Water')) ||
1216
+ (field.hasWeather('Rain') && move.hasType('Fire'))) {
1217
+ baseDamage = (0, util_2.pokeRound)((0, util_2.OF32)(baseDamage * 2048) / 4096);
1218
+ desc.weather = field.weather;
1219
+ }
1220
+ }
1221
+ if (isCritical) {
1222
+ baseDamage = Math.floor((0, util_2.OF32)(baseDamage * 1.5));
1223
+ desc.isCritical = isCritical;
1224
+ }
1225
+ return baseDamage;
1226
+ }
1227
+ function calculateFinalModsSMSSSV(gen, attacker, defender, move, field, desc, isCritical, typeEffectiveness, hitCount) {
1228
+ if (isCritical === void 0) { isCritical = false; }
1229
+ if (hitCount === void 0) { hitCount = 0; }
1230
+ var finalMods = [];
1231
+ if (field.defenderSide.isReflect && move.category === 'Physical' &&
1232
+ !isCritical && !field.defenderSide.isAuroraVeil) {
1233
+ finalMods.push(field.gameType !== 'Singles' ? 2732 : 2048);
1234
+ desc.isReflect = true;
1235
+ }
1236
+ else if (field.defenderSide.isLightScreen && move.category === 'Special' &&
1237
+ !isCritical && !field.defenderSide.isAuroraVeil) {
1238
+ finalMods.push(field.gameType !== 'Singles' ? 2732 : 2048);
1239
+ desc.isLightScreen = true;
1240
+ }
1241
+ if (field.defenderSide.isAuroraVeil && !isCritical) {
1242
+ finalMods.push(field.gameType !== 'Singles' ? 2732 : 2048);
1243
+ desc.isAuroraVeil = true;
1244
+ }
1245
+ if (attacker.hasAbility('Neuroforce') && typeEffectiveness > 1) {
1246
+ finalMods.push(5120);
1247
+ desc.attackerAbility = attacker.ability;
1248
+ }
1249
+ else if (attacker.hasAbility('Sniper') && isCritical) {
1250
+ finalMods.push(6144);
1251
+ desc.attackerAbility = attacker.ability;
1252
+ }
1253
+ else if (attacker.hasAbility('Tinted Lens') && typeEffectiveness < 1) {
1254
+ finalMods.push(8192);
1255
+ desc.attackerAbility = attacker.ability;
1256
+ }
1257
+ if (defender.isDynamaxed && move.named('Dynamax Cannon', 'Behemoth Blade', 'Behemoth Bash')) {
1258
+ finalMods.push(8192);
1259
+ }
1260
+ if (defender.hasAbility('Multiscale', 'Shadow Shield') &&
1261
+ defender.curHP() === defender.maxHP() &&
1262
+ hitCount === 0 &&
1263
+ (!field.defenderSide.isSR && (!field.defenderSide.spikes || defender.hasType('Flying')) ||
1264
+ defender.hasItem('Heavy-Duty Boots')) && !attacker.hasAbility('Parental Bond (Child)')) {
1265
+ finalMods.push(2048);
1266
+ desc.defenderAbility = defender.ability;
1267
+ }
1268
+ if (defender.hasAbility('Fluffy') && move.flags.contact && !attacker.hasAbility('Long Reach')) {
1269
+ finalMods.push(2048);
1270
+ desc.defenderAbility = defender.ability;
1271
+ }
1272
+ else if ((defender.hasAbility('Punk Rock') && move.flags.sound) ||
1273
+ (defender.hasAbility('Ice Scales') && move.category === 'Special')) {
1274
+ finalMods.push(2048);
1275
+ desc.defenderAbility = defender.ability;
1276
+ }
1277
+ if (defender.hasAbility('Solid Rock', 'Filter', 'Prism Armor') && typeEffectiveness > 1) {
1278
+ finalMods.push(3072);
1279
+ desc.defenderAbility = defender.ability;
1280
+ }
1281
+ if (field.defenderSide.isFriendGuard) {
1282
+ finalMods.push(3072);
1283
+ desc.isFriendGuard = true;
1284
+ }
1285
+ if (defender.hasAbility('Fluffy') && move.hasType('Fire')) {
1286
+ finalMods.push(8192);
1287
+ desc.defenderAbility = defender.ability;
1288
+ }
1289
+ if (attacker.hasItem('Expert Belt') && typeEffectiveness > 1 && !move.isZ) {
1290
+ finalMods.push(4915);
1291
+ desc.attackerItem = attacker.item;
1292
+ }
1293
+ else if (attacker.hasItem('Life Orb')) {
1294
+ finalMods.push(5324);
1295
+ desc.attackerItem = attacker.item;
1296
+ }
1297
+ else if (attacker.hasItem('Metronome') && move.timesUsedWithMetronome >= 1) {
1298
+ var timesUsedWithMetronome = Math.floor(move.timesUsedWithMetronome);
1299
+ if (timesUsedWithMetronome <= 4) {
1300
+ finalMods.push(4096 + timesUsedWithMetronome * 819);
1301
+ }
1302
+ else {
1303
+ finalMods.push(8192);
1304
+ }
1305
+ desc.attackerItem = attacker.item;
1306
+ }
1307
+ if (move.hasType((0, items_1.getBerryResistType)(defender.item)) &&
1308
+ (typeEffectiveness > 1 || move.hasType('Normal')) &&
1309
+ hitCount === 0 &&
1310
+ !attacker.hasAbility('Unnerve', 'As One (Glastrier)', 'As One (Spectrier)')) {
1311
+ if (defender.hasAbility('Ripen')) {
1312
+ finalMods.push(1024);
1313
+ }
1314
+ else {
1315
+ finalMods.push(2048);
1316
+ }
1317
+ desc.defenderItem = defender.item;
1318
+ }
1319
+ return finalMods;
1320
+ }
1321
+ exports.calculateFinalModsSMSSSV = calculateFinalModsSMSSSV;
1322
+ function hasTerrainSeed(pokemon) {
1323
+ return pokemon.hasItem('Electric Seed', 'Misty Seed', 'Grassy Seed', 'Psychic Seed');
1324
+ }
1325
+ //# sourceMappingURL=gen789.js.map