@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.
- package/.eslintignore +2 -0
- package/.eslintrc +12 -0
- package/bundle +107 -0
- package/dist/adaptable.d.ts +6 -0
- package/dist/adaptable.js +28 -0
- package/dist/adaptable.js.map +1 -0
- package/dist/calc.d.ts +6 -0
- package/dist/calc.js +26 -0
- package/dist/calc.js.map +1 -0
- package/dist/data/abilities.d.ts +15 -0
- package/dist/data/abilities.js +448 -0
- package/dist/data/abilities.js.map +1 -0
- package/dist/data/index.d.ts +2 -0
- package/dist/data/index.js +30 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/interface.d.ts +150 -0
- package/dist/data/interface.js +3 -0
- package/dist/data/interface.js.map +1 -0
- package/dist/data/items.d.ts +24 -0
- package/dist/data/items.js +708 -0
- package/dist/data/items.js.map +1 -0
- package/dist/data/moves.d.ts +86 -0
- package/dist/data/moves.js +5014 -0
- package/dist/data/moves.js.map +1 -0
- package/dist/data/natures.d.ts +17 -0
- package/dist/data/natures.js +127 -0
- package/dist/data/natures.js.map +1 -0
- package/dist/data/production.min.js +1 -0
- package/dist/data/species.d.ts +48 -0
- package/dist/data/species.js +10126 -0
- package/dist/data/species.js.map +1 -0
- package/dist/data/types.d.ts +23 -0
- package/dist/data/types.js +538 -0
- package/dist/data/types.js.map +1 -0
- package/dist/desc.d.ts +65 -0
- package/dist/desc.js +866 -0
- package/dist/desc.js.map +1 -0
- package/dist/field.d.ts +49 -0
- package/dist/field.js +111 -0
- package/dist/field.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/items.d.ts +13 -0
- package/dist/items.js +434 -0
- package/dist/items.js.map +1 -0
- package/dist/mechanics/gen12.d.ts +6 -0
- package/dist/mechanics/gen12.js +271 -0
- package/dist/mechanics/gen12.js.map +1 -0
- package/dist/mechanics/gen3.d.ts +11 -0
- package/dist/mechanics/gen3.js +371 -0
- package/dist/mechanics/gen3.js.map +1 -0
- package/dist/mechanics/gen4.d.ts +11 -0
- package/dist/mechanics/gen4.js +596 -0
- package/dist/mechanics/gen4.js.map +1 -0
- package/dist/mechanics/gen56.d.ts +13 -0
- package/dist/mechanics/gen56.js +836 -0
- package/dist/mechanics/gen56.js.map +1 -0
- package/dist/mechanics/gen789.d.ts +14 -0
- package/dist/mechanics/gen789.js +1325 -0
- package/dist/mechanics/gen789.js.map +1 -0
- package/dist/mechanics/util.d.ts +39 -0
- package/dist/mechanics/util.js +675 -0
- package/dist/mechanics/util.js.map +1 -0
- package/dist/move.d.ts +50 -0
- package/dist/move.js +324 -0
- package/dist/move.js.map +1 -0
- package/dist/pokemon.d.ts +55 -0
- package/dist/pokemon.js +240 -0
- package/dist/pokemon.js.map +1 -0
- package/dist/production.min.js +1 -0
- package/dist/result.d.ts +34 -0
- package/dist/result.js +94 -0
- package/dist/result.js.map +1 -0
- package/dist/state.d.ts +77 -0
- package/dist/state.js +3 -0
- package/dist/state.js.map +1 -0
- package/dist/stats.d.ts +26 -0
- package/dist/stats.js +183 -0
- package/dist/stats.js.map +1 -0
- package/dist/test/calc.test.d.ts +1 -0
- package/dist/test/calc.test.js +1297 -0
- package/dist/test/calc.test.js.map +1 -0
- package/dist/test/data.test.d.ts +1 -0
- package/dist/test/data.test.js +368 -0
- package/dist/test/data.test.js.map +1 -0
- package/dist/test/gen.d.ts +135 -0
- package/dist/test/gen.js +636 -0
- package/dist/test/gen.js.map +1 -0
- package/dist/test/helper.d.ts +55 -0
- package/dist/test/helper.js +174 -0
- package/dist/test/helper.js.map +1 -0
- package/dist/test/move.test.d.ts +1 -0
- package/dist/test/move.test.js +14 -0
- package/dist/test/move.test.js.map +1 -0
- package/dist/test/pokemon.test.d.ts +1 -0
- package/dist/test/pokemon.test.js +102 -0
- package/dist/test/pokemon.test.js.map +1 -0
- package/dist/test/stats.test.d.ts +1 -0
- package/dist/test/stats.test.js +64 -0
- package/dist/test/stats.test.js.map +1 -0
- package/dist/test/utils.test.d.ts +1 -0
- package/dist/test/utils.test.js +19 -0
- package/dist/test/utils.test.js.map +1 -0
- package/dist/util.d.ts +17 -0
- package/dist/util.js +115 -0
- package/dist/util.js.map +1 -0
- package/jest.config.js +11 -0
- package/package.json +40 -0
- package/src/adaptable.ts +12 -0
- package/src/calc.ts +40 -0
- package/src/data/abilities.ts +383 -0
- package/src/data/index.ts +36 -0
- package/src/data/interface.ts +176 -0
- package/src/data/items.ts +632 -0
- package/src/data/moves.ts +5028 -0
- package/src/data/natures.ts +65 -0
- package/src/data/species.ts +10098 -0
- package/src/data/types.ts +478 -0
- package/src/desc.ts +1063 -0
- package/src/field.ts +124 -0
- package/src/index.ts +156 -0
- package/src/items.ts +423 -0
- package/src/mechanics/gen12.ts +297 -0
- package/src/mechanics/gen3.ts +444 -0
- package/src/mechanics/gen4.ts +702 -0
- package/src/mechanics/gen56.ts +1134 -0
- package/src/mechanics/gen789.ts +1788 -0
- package/src/mechanics/util.ts +676 -0
- package/src/move.ts +337 -0
- package/src/pokemon.ts +244 -0
- package/src/result.ts +106 -0
- package/src/state.ts +81 -0
- package/src/stats.ts +213 -0
- package/src/test/calc.test.ts +1588 -0
- package/src/test/data.test.ts +129 -0
- package/src/test/gen.ts +514 -0
- package/src/test/helper.ts +185 -0
- package/src/test/move.test.ts +13 -0
- package/src/test/pokemon.test.ts +121 -0
- package/src/test/stats.test.ts +84 -0
- package/src/test/utils.test.ts +18 -0
- package/src/util.ts +153 -0
- package/tsconfig.json +10 -0
package/dist/desc.js
ADDED
|
@@ -0,0 +1,866 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
3
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
4
|
+
if (!m) return o;
|
|
5
|
+
var i = m.call(o), r, ar = [], e;
|
|
6
|
+
try {
|
|
7
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
8
|
+
}
|
|
9
|
+
catch (error) { e = { error: error }; }
|
|
10
|
+
finally {
|
|
11
|
+
try {
|
|
12
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
13
|
+
}
|
|
14
|
+
finally { if (e) throw e.error; }
|
|
15
|
+
}
|
|
16
|
+
return ar;
|
|
17
|
+
};
|
|
18
|
+
exports.__esModule = true;
|
|
19
|
+
exports.getKOChance = exports.getRecoil = exports.getRecovery = exports.displayMove = exports.display = void 0;
|
|
20
|
+
var result_1 = require("./result");
|
|
21
|
+
var util_1 = require("./util");
|
|
22
|
+
var util_2 = require("./mechanics/util");
|
|
23
|
+
function display(gen, attacker, defender, move, field, damage, rawDesc, notation, err) {
|
|
24
|
+
if (notation === void 0) { notation = '%'; }
|
|
25
|
+
if (err === void 0) { err = true; }
|
|
26
|
+
var _a = __read((0, result_1.damageRange)(damage), 2), minDamage = _a[0], maxDamage = _a[1];
|
|
27
|
+
var min = (typeof minDamage === 'number' ? minDamage : minDamage[0] + minDamage[1]);
|
|
28
|
+
var max = (typeof maxDamage === 'number' ? maxDamage : maxDamage[0] + maxDamage[1]);
|
|
29
|
+
var minDisplay = toDisplay(notation, min, defender.maxHP());
|
|
30
|
+
var maxDisplay = toDisplay(notation, max, defender.maxHP());
|
|
31
|
+
var desc = buildDescription(rawDesc, attacker, defender);
|
|
32
|
+
var damageText = "".concat(min, "-").concat(max, " (").concat(minDisplay, " - ").concat(maxDisplay).concat(notation, ")");
|
|
33
|
+
if (move.category === 'Status' && !move.named('Nature Power'))
|
|
34
|
+
return "".concat(desc, ": ").concat(damageText);
|
|
35
|
+
var koChanceText = getKOChance(gen, attacker, defender, move, field, damage, err).text;
|
|
36
|
+
return koChanceText ? "".concat(desc, ": ").concat(damageText, " -- ").concat(koChanceText) : "".concat(desc, ": ").concat(damageText);
|
|
37
|
+
}
|
|
38
|
+
exports.display = display;
|
|
39
|
+
function displayMove(gen, attacker, defender, move, damage, notation) {
|
|
40
|
+
if (notation === void 0) { notation = '%'; }
|
|
41
|
+
var _a = __read((0, result_1.damageRange)(damage), 2), minDamage = _a[0], maxDamage = _a[1];
|
|
42
|
+
var min = (typeof minDamage === 'number' ? minDamage : minDamage[0] + minDamage[1]);
|
|
43
|
+
var max = (typeof maxDamage === 'number' ? maxDamage : maxDamage[0] + maxDamage[1]);
|
|
44
|
+
var minDisplay = toDisplay(notation, min, defender.maxHP());
|
|
45
|
+
var maxDisplay = toDisplay(notation, max, defender.maxHP());
|
|
46
|
+
var recoveryText = getRecovery(gen, attacker, defender, move, damage, notation).text;
|
|
47
|
+
var recoilText = getRecoil(gen, attacker, defender, move, damage, notation).text;
|
|
48
|
+
return "".concat(minDisplay, " - ").concat(maxDisplay).concat(notation).concat(recoveryText &&
|
|
49
|
+
" (".concat(recoveryText, ")")).concat(recoilText && " (".concat(recoilText, ")"));
|
|
50
|
+
}
|
|
51
|
+
exports.displayMove = displayMove;
|
|
52
|
+
function getRecovery(gen, attacker, defender, move, damage, notation) {
|
|
53
|
+
if (notation === void 0) { notation = '%'; }
|
|
54
|
+
var _a = __read((0, result_1.damageRange)(damage), 2), minDamage = _a[0], maxDamage = _a[1];
|
|
55
|
+
var minD = typeof minDamage === 'number' ? [minDamage] : minDamage;
|
|
56
|
+
var maxD = typeof maxDamage === 'number' ? [maxDamage] : maxDamage;
|
|
57
|
+
var recovery = [0, 0];
|
|
58
|
+
var text = '';
|
|
59
|
+
var ignoresShellBell = gen.num === 3 && move.named('Doom Desire', 'Future Sight');
|
|
60
|
+
if (attacker.hasItem('Shell Bell') && !ignoresShellBell) {
|
|
61
|
+
var max = Math.round(defender.maxHP() / 8);
|
|
62
|
+
for (var i = 0; i < minD.length; i++) {
|
|
63
|
+
recovery[0] += Math.min(Math.round(minD[i] * move.hits / 8), max);
|
|
64
|
+
recovery[1] += Math.min(Math.round(maxD[i] * move.hits / 8), max);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (move.named('G-Max Finale')) {
|
|
68
|
+
recovery[0] = recovery[1] = Math.round(attacker.maxHP() / 6);
|
|
69
|
+
}
|
|
70
|
+
if (move.named('Pain Split')) {
|
|
71
|
+
var average = Math.floor((attacker.curHP() + defender.curHP()) / 2);
|
|
72
|
+
recovery[0] = recovery[1] = average - attacker.curHP();
|
|
73
|
+
}
|
|
74
|
+
if (move.drain) {
|
|
75
|
+
var percentHealed = move.drain[0] / move.drain[1];
|
|
76
|
+
var max = Math.round(defender.maxHP() * percentHealed);
|
|
77
|
+
for (var i = 0; i < minD.length; i++) {
|
|
78
|
+
var range = [minD[i], maxD[i]];
|
|
79
|
+
for (var j in recovery) {
|
|
80
|
+
var drained = Math.round(range[j] * percentHealed);
|
|
81
|
+
if (attacker.hasItem('Big Root'))
|
|
82
|
+
drained = Math.trunc(drained * 5324 / 4096);
|
|
83
|
+
recovery[j] += Math.min(drained * move.hits, max);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (recovery[1] === 0)
|
|
88
|
+
return { recovery: recovery, text: text };
|
|
89
|
+
var minHealthRecovered = toDisplay(notation, recovery[0], attacker.maxHP());
|
|
90
|
+
var maxHealthRecovered = toDisplay(notation, recovery[1], attacker.maxHP());
|
|
91
|
+
var change = recovery[0] > 0 ? 'recovered' : 'lost';
|
|
92
|
+
text = "".concat(minHealthRecovered, " - ").concat(maxHealthRecovered).concat(notation, " ").concat(change);
|
|
93
|
+
return { recovery: recovery, text: text };
|
|
94
|
+
}
|
|
95
|
+
exports.getRecovery = getRecovery;
|
|
96
|
+
function getRecoil(gen, attacker, defender, move, damage, notation) {
|
|
97
|
+
if (notation === void 0) { notation = '%'; }
|
|
98
|
+
var _a = __read((0, result_1.damageRange)(damage), 2), minDamage = _a[0], maxDamage = _a[1];
|
|
99
|
+
var min = (typeof minDamage === 'number' ? minDamage : minDamage[0] + minDamage[1]) * move.hits;
|
|
100
|
+
var max = (typeof maxDamage === 'number' ? maxDamage : maxDamage[0] + maxDamage[1]) * move.hits;
|
|
101
|
+
var recoil = [0, 0];
|
|
102
|
+
var text = '';
|
|
103
|
+
var damageOverflow = minDamage > defender.curHP() || maxDamage > defender.curHP();
|
|
104
|
+
if (move.recoil) {
|
|
105
|
+
var mod = (move.recoil[0] / move.recoil[1]) * 100;
|
|
106
|
+
var minRecoilDamage = void 0, maxRecoilDamage = void 0;
|
|
107
|
+
if (damageOverflow) {
|
|
108
|
+
minRecoilDamage =
|
|
109
|
+
toDisplay(notation, defender.curHP() * mod, attacker.maxHP(), 100);
|
|
110
|
+
maxRecoilDamage =
|
|
111
|
+
toDisplay(notation, defender.curHP() * mod, attacker.maxHP(), 100);
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
minRecoilDamage = toDisplay(notation, Math.min(min, defender.curHP()) * mod, attacker.maxHP(), 100);
|
|
115
|
+
maxRecoilDamage = toDisplay(notation, Math.min(max, defender.curHP()) * mod, attacker.maxHP(), 100);
|
|
116
|
+
}
|
|
117
|
+
if (!attacker.hasAbility('Rock Head')) {
|
|
118
|
+
recoil = [minRecoilDamage, maxRecoilDamage];
|
|
119
|
+
text = "".concat(minRecoilDamage, " - ").concat(maxRecoilDamage).concat(notation, " recoil damage");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (move.hasCrashDamage) {
|
|
123
|
+
var genMultiplier = gen.num === 2 ? 12.5 : gen.num >= 3 ? 50 : 1;
|
|
124
|
+
var minRecoilDamage = void 0, maxRecoilDamage = void 0;
|
|
125
|
+
if (damageOverflow && gen.num !== 2) {
|
|
126
|
+
minRecoilDamage =
|
|
127
|
+
toDisplay(notation, defender.curHP() * genMultiplier, attacker.maxHP(), 100);
|
|
128
|
+
maxRecoilDamage =
|
|
129
|
+
toDisplay(notation, defender.curHP() * genMultiplier, attacker.maxHP(), 100);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
minRecoilDamage = toDisplay(notation, Math.min(min, defender.maxHP()) * genMultiplier, attacker.maxHP(), 100);
|
|
133
|
+
maxRecoilDamage = toDisplay(notation, Math.min(max, defender.maxHP()) * genMultiplier, attacker.maxHP(), 100);
|
|
134
|
+
}
|
|
135
|
+
recoil = [minRecoilDamage, maxRecoilDamage];
|
|
136
|
+
switch (gen.num) {
|
|
137
|
+
case 1:
|
|
138
|
+
recoil = toDisplay(notation, 1, attacker.maxHP());
|
|
139
|
+
text = '1hp damage on miss';
|
|
140
|
+
break;
|
|
141
|
+
case 2:
|
|
142
|
+
case 3:
|
|
143
|
+
case 4:
|
|
144
|
+
if (defender.hasType('Ghost')) {
|
|
145
|
+
if (gen.num === 4) {
|
|
146
|
+
var gen4CrashDamage = Math.floor(((defender.maxHP() * 0.5) / attacker.maxHP()) * 100);
|
|
147
|
+
recoil = notation === '%' ? gen4CrashDamage : Math.floor((gen4CrashDamage / 100) * 48);
|
|
148
|
+
text = "".concat(gen4CrashDamage, "% crash damage");
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
recoil = 0;
|
|
152
|
+
text = 'no crash damage on Ghost types';
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
text = "".concat(minRecoilDamage, " - ").concat(maxRecoilDamage).concat(notation, " crash damage on miss");
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
159
|
+
default:
|
|
160
|
+
recoil = notation === '%' ? 24 : 50;
|
|
161
|
+
text = '50% crash damage';
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (move.struggleRecoil) {
|
|
165
|
+
recoil = notation === '%' ? 12 : 25;
|
|
166
|
+
text = '25% struggle damage';
|
|
167
|
+
if (gen.num === 4)
|
|
168
|
+
text += ' (rounded down)';
|
|
169
|
+
}
|
|
170
|
+
else if (move.mindBlownRecoil) {
|
|
171
|
+
recoil = notation === '%' ? 24 : 50;
|
|
172
|
+
text = '50% recoil damage';
|
|
173
|
+
}
|
|
174
|
+
return { recoil: recoil, text: text };
|
|
175
|
+
}
|
|
176
|
+
exports.getRecoil = getRecoil;
|
|
177
|
+
function getKOChance(gen, attacker, defender, move, field, damage, err) {
|
|
178
|
+
if (err === void 0) { err = true; }
|
|
179
|
+
damage = combine(damage);
|
|
180
|
+
if (isNaN(damage[0])) {
|
|
181
|
+
(0, util_1.error)(err, 'damage[0] must be a number.');
|
|
182
|
+
return { chance: 0, n: 0, text: '' };
|
|
183
|
+
}
|
|
184
|
+
if (damage[damage.length - 1] === 0) {
|
|
185
|
+
(0, util_1.error)(err, 'damage[damage.length - 1] === 0.');
|
|
186
|
+
return { chance: 0, n: 0, text: '' };
|
|
187
|
+
}
|
|
188
|
+
if (move.timesUsed === undefined)
|
|
189
|
+
move.timesUsed = 1;
|
|
190
|
+
if (move.timesUsedWithMetronome === undefined)
|
|
191
|
+
move.timesUsedWithMetronome = 1;
|
|
192
|
+
if (damage[0] >= defender.maxHP() && move.timesUsed === 1 && move.timesUsedWithMetronome === 1) {
|
|
193
|
+
return { chance: 1, n: 1, text: 'guaranteed OHKO' };
|
|
194
|
+
}
|
|
195
|
+
var hazards = getHazards(gen, defender, field.defenderSide);
|
|
196
|
+
var eot = getEndOfTurn(gen, attacker, defender, move, field);
|
|
197
|
+
var toxicCounter = defender.hasStatus('tox') && !defender.hasAbility('Magic Guard', 'Poison Heal')
|
|
198
|
+
? defender.toxicCounter : 0;
|
|
199
|
+
var qualifier = move.hits > 1 ? 'approx. ' : '';
|
|
200
|
+
var hazardsText = hazards.texts.length > 0
|
|
201
|
+
? ' after ' + serializeText(hazards.texts)
|
|
202
|
+
: '';
|
|
203
|
+
var afterText = hazards.texts.length > 0 || eot.texts.length > 0
|
|
204
|
+
? ' after ' + serializeText(hazards.texts.concat(eot.texts))
|
|
205
|
+
: '';
|
|
206
|
+
var afterTextNoHazards = eot.texts.length > 0 ? ' after ' + serializeText(eot.texts) : '';
|
|
207
|
+
function roundChance(chance) {
|
|
208
|
+
return Math.max(Math.min(Math.round(chance * 1000), 999), 1) / 10;
|
|
209
|
+
}
|
|
210
|
+
function KOChance(chanceWithoutEot, chanceWithEot, n, multipleTurns) {
|
|
211
|
+
if (multipleTurns === void 0) { multipleTurns = false; }
|
|
212
|
+
var KOTurnText = n === 1 ? 'OHKO'
|
|
213
|
+
: (multipleTurns ? "KO in ".concat(n, " turns") : "".concat(n, "HKO"));
|
|
214
|
+
var text = qualifier;
|
|
215
|
+
var chance = undefined;
|
|
216
|
+
if (chanceWithoutEot === undefined || chanceWithEot === undefined) {
|
|
217
|
+
text += "possible ".concat(KOTurnText);
|
|
218
|
+
}
|
|
219
|
+
else if (chanceWithoutEot + chanceWithEot === 0) {
|
|
220
|
+
chance = 0;
|
|
221
|
+
text += 'not a KO';
|
|
222
|
+
}
|
|
223
|
+
else if (chanceWithoutEot === 1) {
|
|
224
|
+
chance = chanceWithoutEot;
|
|
225
|
+
if (qualifier === '')
|
|
226
|
+
text += 'guaranteed ';
|
|
227
|
+
text += "OHKO".concat(hazardsText);
|
|
228
|
+
}
|
|
229
|
+
else if (chanceWithoutEot > 0) {
|
|
230
|
+
chance = chanceWithEot;
|
|
231
|
+
if (chanceWithEot === 1) {
|
|
232
|
+
text += "".concat(roundChance(chanceWithoutEot), "% chance to ").concat(KOTurnText).concat(hazardsText, " ") +
|
|
233
|
+
"(guaranteed ".concat(KOTurnText).concat(afterTextNoHazards, ")");
|
|
234
|
+
}
|
|
235
|
+
else if (chanceWithEot > chanceWithoutEot) {
|
|
236
|
+
text += "".concat(roundChance(chanceWithoutEot), "% chance to ").concat(KOTurnText).concat(hazardsText, " ") +
|
|
237
|
+
"(".concat(qualifier).concat(roundChance(chanceWithEot), "% chance to ") +
|
|
238
|
+
"".concat(KOTurnText).concat(afterTextNoHazards, ")");
|
|
239
|
+
}
|
|
240
|
+
else if (chanceWithoutEot > 0) {
|
|
241
|
+
text += "".concat(roundChance(chanceWithoutEot), "% chance to ").concat(KOTurnText).concat(hazardsText);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
else if (chanceWithoutEot === 0) {
|
|
245
|
+
chance = chanceWithEot;
|
|
246
|
+
if (chanceWithEot === 1) {
|
|
247
|
+
if (qualifier === '')
|
|
248
|
+
text += 'guaranteed ';
|
|
249
|
+
text += "".concat(KOTurnText).concat(afterText);
|
|
250
|
+
}
|
|
251
|
+
else if (chanceWithEot > 0) {
|
|
252
|
+
text += "".concat(roundChance(chanceWithEot), "% chance to ").concat(KOTurnText).concat(afterText);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return { chance: chance, n: n, text: text };
|
|
256
|
+
}
|
|
257
|
+
if ((move.timesUsed === 1 && move.timesUsedWithMetronome === 1) || move.isZ) {
|
|
258
|
+
var chance = computeKOChance(damage, defender.curHP() - hazards.damage, 0, 1, 1, defender.maxHP(), 0);
|
|
259
|
+
var chanceWithEot = computeKOChance(damage, defender.curHP() - hazards.damage, eot.damage, 1, 1, defender.maxHP(), toxicCounter);
|
|
260
|
+
if (chance + chanceWithEot > 0)
|
|
261
|
+
return KOChance(chance, chanceWithEot, 1);
|
|
262
|
+
if (damage.length === 256) {
|
|
263
|
+
qualifier = 'approx. ';
|
|
264
|
+
}
|
|
265
|
+
for (var i = 2; i <= 4; i++) {
|
|
266
|
+
var chance_1 = computeKOChance(damage, defender.curHP() - hazards.damage, eot.damage, i, 1, defender.maxHP(), toxicCounter);
|
|
267
|
+
if (chance_1 > 0)
|
|
268
|
+
return KOChance(0, chance_1, i);
|
|
269
|
+
}
|
|
270
|
+
for (var i = 5; i <= 9; i++) {
|
|
271
|
+
if (predictTotal(damage[0], eot.damage, i, 1, toxicCounter, defender.maxHP()) >=
|
|
272
|
+
defender.curHP() - hazards.damage) {
|
|
273
|
+
return KOChance(0, 1, i);
|
|
274
|
+
}
|
|
275
|
+
else if (predictTotal(damage[damage.length - 1], eot.damage, i, 1, toxicCounter, defender.maxHP()) >=
|
|
276
|
+
defender.curHP() - hazards.damage) {
|
|
277
|
+
return KOChance(undefined, undefined, i);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
var chance = computeKOChance(damage, defender.maxHP() - hazards.damage, eot.damage, move.hits || 1, move.timesUsed || 1, defender.maxHP(), toxicCounter);
|
|
283
|
+
if (chance > 0)
|
|
284
|
+
return KOChance(0, chance, move.timesUsed, chance === 1);
|
|
285
|
+
if (predictTotal(damage[0], eot.damage, 1, move.timesUsed, toxicCounter, defender.maxHP()) >=
|
|
286
|
+
defender.curHP() - hazards.damage) {
|
|
287
|
+
return KOChance(0, 1, move.timesUsed, true);
|
|
288
|
+
}
|
|
289
|
+
else if (predictTotal(damage[damage.length - 1], eot.damage, 1, move.timesUsed, toxicCounter, defender.maxHP()) >=
|
|
290
|
+
defender.curHP() - hazards.damage) {
|
|
291
|
+
return KOChance(undefined, undefined, move.timesUsed, true);
|
|
292
|
+
}
|
|
293
|
+
return KOChance(0, 0, move.timesUsed);
|
|
294
|
+
}
|
|
295
|
+
return { chance: 0, n: 0, text: '' };
|
|
296
|
+
}
|
|
297
|
+
exports.getKOChance = getKOChance;
|
|
298
|
+
function combine(damage) {
|
|
299
|
+
if (typeof damage === 'number')
|
|
300
|
+
return [damage];
|
|
301
|
+
if (damage.length > 2) {
|
|
302
|
+
if (damage[0] > damage[damage.length - 1])
|
|
303
|
+
damage = damage.slice().sort();
|
|
304
|
+
return damage;
|
|
305
|
+
}
|
|
306
|
+
if (typeof damage[0] === 'number' && typeof damage[1] === 'number') {
|
|
307
|
+
return [damage[0] + damage[1]];
|
|
308
|
+
}
|
|
309
|
+
var d = damage;
|
|
310
|
+
var combined = [];
|
|
311
|
+
for (var i = 0; i < d[0].length; i++) {
|
|
312
|
+
for (var j = 0; j < d[1].length; j++) {
|
|
313
|
+
combined.push(d[0][i] + d[1][j]);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return combined.sort();
|
|
317
|
+
}
|
|
318
|
+
var TRAPPING = [
|
|
319
|
+
'Bind', 'Clamp', 'Fire Spin', 'Infestation', 'Magma Storm', 'Sand Tomb',
|
|
320
|
+
'Thunder Cage', 'Whirlpool', 'Wrap', 'G-Max Sandblast', 'G-Max Centiferno',
|
|
321
|
+
];
|
|
322
|
+
function getHazards(gen, defender, defenderSide) {
|
|
323
|
+
var damage = 0;
|
|
324
|
+
var texts = [];
|
|
325
|
+
if (defender.hasItem('Heavy-Duty Boots')) {
|
|
326
|
+
return { damage: damage, texts: texts };
|
|
327
|
+
}
|
|
328
|
+
if (defenderSide.isSR && !defender.hasAbility('Magic Guard', 'Mountaineer')) {
|
|
329
|
+
var rockType = gen.types.get('rock');
|
|
330
|
+
var effectiveness = rockType.effectiveness[defender.types[0]] *
|
|
331
|
+
(defender.types[1] ? rockType.effectiveness[defender.types[1]] : 1);
|
|
332
|
+
damage += Math.floor((effectiveness * defender.maxHP()) / 8);
|
|
333
|
+
texts.push('Stealth Rock');
|
|
334
|
+
}
|
|
335
|
+
if (defenderSide.steelsurge && !defender.hasAbility('Magic Guard', 'Mountaineer')) {
|
|
336
|
+
var steelType = gen.types.get('steel');
|
|
337
|
+
var effectiveness = steelType.effectiveness[defender.types[0]] *
|
|
338
|
+
(defender.types[1] ? steelType.effectiveness[defender.types[1]] : 1);
|
|
339
|
+
damage += Math.floor((effectiveness * defender.maxHP()) / 8);
|
|
340
|
+
texts.push('Steelsurge');
|
|
341
|
+
}
|
|
342
|
+
if (!defender.hasType('Flying') &&
|
|
343
|
+
!defender.hasAbility('Magic Guard', 'Levitate') &&
|
|
344
|
+
!defender.hasItem('Air Balloon')) {
|
|
345
|
+
if (defenderSide.spikes === 1) {
|
|
346
|
+
damage += Math.floor(defender.maxHP() / 8);
|
|
347
|
+
if (gen.num === 2) {
|
|
348
|
+
texts.push('Spikes');
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
texts.push('1 layer of Spikes');
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else if (defenderSide.spikes === 2) {
|
|
355
|
+
damage += Math.floor(defender.maxHP() / 6);
|
|
356
|
+
texts.push('2 layers of Spikes');
|
|
357
|
+
}
|
|
358
|
+
else if (defenderSide.spikes === 3) {
|
|
359
|
+
damage += Math.floor(defender.maxHP() / 4);
|
|
360
|
+
texts.push('3 layers of Spikes');
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (isNaN(damage)) {
|
|
364
|
+
damage = 0;
|
|
365
|
+
}
|
|
366
|
+
return { damage: damage, texts: texts };
|
|
367
|
+
}
|
|
368
|
+
function getEndOfTurn(gen, attacker, defender, move, field) {
|
|
369
|
+
var damage = 0;
|
|
370
|
+
var texts = [];
|
|
371
|
+
if (field.hasWeather('Sun', 'Harsh Sunshine')) {
|
|
372
|
+
if (defender.hasAbility('Dry Skin', 'Solar Power')) {
|
|
373
|
+
damage -= Math.floor(defender.maxHP() / 8);
|
|
374
|
+
texts.push(defender.ability + ' damage');
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else if (field.hasWeather('Rain', 'Heavy Rain')) {
|
|
378
|
+
if (defender.hasAbility('Dry Skin')) {
|
|
379
|
+
damage += Math.floor(defender.maxHP() / 8);
|
|
380
|
+
texts.push('Dry Skin recovery');
|
|
381
|
+
}
|
|
382
|
+
else if (defender.hasAbility('Rain Dish')) {
|
|
383
|
+
damage += Math.floor(defender.maxHP() / 16);
|
|
384
|
+
texts.push('Rain Dish recovery');
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
else if (field.hasWeather('Sand')) {
|
|
388
|
+
if (!defender.hasType('Rock', 'Ground', 'Steel') &&
|
|
389
|
+
!defender.hasAbility('Magic Guard', 'Overcoat', 'Sand Force', 'Sand Rush', 'Sand Veil') &&
|
|
390
|
+
!defender.hasItem('Safety Goggles')) {
|
|
391
|
+
damage -= Math.floor(defender.maxHP() / (gen.num === 2 ? 8 : 16));
|
|
392
|
+
texts.push('sandstorm damage');
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
else if (field.hasWeather('Hail', 'Snow')) {
|
|
396
|
+
if (defender.hasAbility('Ice Body')) {
|
|
397
|
+
damage += Math.floor(defender.maxHP() / 16);
|
|
398
|
+
texts.push('Ice Body recovery');
|
|
399
|
+
}
|
|
400
|
+
else if (!defender.hasType('Ice') &&
|
|
401
|
+
!defender.hasAbility('Magic Guard', 'Overcoat', 'Snow Cloak') &&
|
|
402
|
+
!defender.hasItem('Safety Goggles') &&
|
|
403
|
+
field.hasWeather('Hail')) {
|
|
404
|
+
damage -= Math.floor(defender.maxHP() / 16);
|
|
405
|
+
texts.push('hail damage');
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
var loseItem = move.named('Knock Off') && !defender.hasAbility('Sticky Hold');
|
|
409
|
+
if (defender.hasItem('Leftovers') && !loseItem) {
|
|
410
|
+
damage += Math.floor(defender.maxHP() / 16);
|
|
411
|
+
texts.push('Leftovers recovery');
|
|
412
|
+
}
|
|
413
|
+
else if (defender.hasItem('Black Sludge') && !loseItem) {
|
|
414
|
+
if (defender.hasType('Poison')) {
|
|
415
|
+
damage += Math.floor(defender.maxHP() / 16);
|
|
416
|
+
texts.push('Black Sludge recovery');
|
|
417
|
+
}
|
|
418
|
+
else if (!defender.hasAbility('Magic Guard', 'Klutz')) {
|
|
419
|
+
damage -= Math.floor(defender.maxHP() / 8);
|
|
420
|
+
texts.push('Black Sludge damage');
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
else if (defender.hasItem('Sticky Barb')) {
|
|
424
|
+
damage -= Math.floor(defender.maxHP() / 8);
|
|
425
|
+
texts.push('Sticky Barb damage');
|
|
426
|
+
}
|
|
427
|
+
if (field.defenderSide.isSeeded) {
|
|
428
|
+
if (!defender.hasAbility('Magic Guard')) {
|
|
429
|
+
damage -= Math.floor(defender.maxHP() / (gen.num >= 2 ? 8 : 16));
|
|
430
|
+
texts.push('Leech Seed damage');
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (field.attackerSide.isSeeded && !attacker.hasAbility('Magic Guard')) {
|
|
434
|
+
var recovery = Math.floor(attacker.maxHP() / (gen.num >= 2 ? 8 : 16));
|
|
435
|
+
if (defender.hasItem('Big Root'))
|
|
436
|
+
recovery = Math.trunc(recovery * 5324 / 4096);
|
|
437
|
+
if (attacker.hasAbility('Liquid Ooze')) {
|
|
438
|
+
damage -= recovery;
|
|
439
|
+
texts.push('Liquid Ooze damage');
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
damage += recovery;
|
|
443
|
+
texts.push('Leech Seed recovery');
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (field.hasTerrain('Grassy')) {
|
|
447
|
+
if ((0, util_2.isGrounded)(defender, field)) {
|
|
448
|
+
damage += Math.floor(defender.maxHP() / 16);
|
|
449
|
+
texts.push('Grassy Terrain recovery');
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (defender.hasStatus('psn')) {
|
|
453
|
+
if (defender.hasAbility('Poison Heal')) {
|
|
454
|
+
damage += Math.floor(defender.maxHP() / 8);
|
|
455
|
+
texts.push('Poison Heal');
|
|
456
|
+
}
|
|
457
|
+
else if (!defender.hasAbility('Magic Guard')) {
|
|
458
|
+
damage -= Math.floor(defender.maxHP() / (gen.num === 1 ? 16 : 8));
|
|
459
|
+
texts.push('poison damage');
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
else if (defender.hasStatus('tox')) {
|
|
463
|
+
if (defender.hasAbility('Poison Heal')) {
|
|
464
|
+
damage += Math.floor(defender.maxHP() / 8);
|
|
465
|
+
texts.push('Poison Heal');
|
|
466
|
+
}
|
|
467
|
+
else if (!defender.hasAbility('Magic Guard')) {
|
|
468
|
+
texts.push('toxic damage');
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
else if (defender.hasStatus('brn')) {
|
|
472
|
+
if (defender.hasAbility('Heatproof')) {
|
|
473
|
+
damage -= Math.floor(defender.maxHP() / (gen.num > 6 ? 32 : 16));
|
|
474
|
+
texts.push('reduced burn damage');
|
|
475
|
+
}
|
|
476
|
+
else if (!defender.hasAbility('Magic Guard')) {
|
|
477
|
+
damage -= Math.floor(defender.maxHP() / (gen.num === 1 || gen.num > 6 ? 16 : 8));
|
|
478
|
+
texts.push('burn damage');
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else if ((defender.hasStatus('slp') || defender.hasAbility('Comatose')) &&
|
|
482
|
+
attacker.hasAbility('isBadDreams') &&
|
|
483
|
+
!defender.hasAbility('Magic Guard')) {
|
|
484
|
+
damage -= Math.floor(defender.maxHP() / 8);
|
|
485
|
+
texts.push('Bad Dreams');
|
|
486
|
+
}
|
|
487
|
+
if (!defender.hasAbility('Magic Guard') && TRAPPING.includes(move.name)) {
|
|
488
|
+
if (attacker.hasItem('Binding Band')) {
|
|
489
|
+
damage -= gen.num > 5 ? Math.floor(defender.maxHP() / 6) : Math.floor(defender.maxHP() / 8);
|
|
490
|
+
texts.push('trapping damage');
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
damage -= gen.num > 5 ? Math.floor(defender.maxHP() / 8) : Math.floor(defender.maxHP() / 16);
|
|
494
|
+
texts.push('trapping damage');
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if (defender.isSaltCure && !defender.hasAbility('Magic Guard')) {
|
|
498
|
+
var isWaterOrSteel = defender.hasType('Water', 'Steel') ||
|
|
499
|
+
(defender.teraType && ['Water', 'Steel'].includes(defender.teraType));
|
|
500
|
+
damage -= Math.floor(defender.maxHP() / (isWaterOrSteel ? 4 : 8));
|
|
501
|
+
texts.push('Salt Cure');
|
|
502
|
+
}
|
|
503
|
+
if (!defender.hasType('Fire') && !defender.hasAbility('Magic Guard') &&
|
|
504
|
+
(move.named('Fire Pledge (Grass Pledge Boosted)', 'Grass Pledge (Fire Pledge Boosted)'))) {
|
|
505
|
+
damage -= Math.floor(defender.maxHP() / 8);
|
|
506
|
+
texts.push('Sea of Fire damage');
|
|
507
|
+
}
|
|
508
|
+
if (!defender.hasAbility('Magic Guard') && !defender.hasType('Grass') &&
|
|
509
|
+
(field.defenderSide.vinelash || move.named('G-Max Vine Lash'))) {
|
|
510
|
+
damage -= Math.floor(defender.maxHP() / 6);
|
|
511
|
+
texts.push('Vine Lash damage');
|
|
512
|
+
}
|
|
513
|
+
if (!defender.hasAbility('Magic Guard') && !defender.hasType('Fire') &&
|
|
514
|
+
(field.defenderSide.wildfire || move.named('G-Max Wildfire'))) {
|
|
515
|
+
damage -= Math.floor(defender.maxHP() / 6);
|
|
516
|
+
texts.push('Wildfire damage');
|
|
517
|
+
}
|
|
518
|
+
if (!defender.hasAbility('Magic Guard') && !defender.hasType('Water') &&
|
|
519
|
+
(field.defenderSide.cannonade || move.named('G-Max Cannonade'))) {
|
|
520
|
+
damage -= Math.floor(defender.maxHP() / 6);
|
|
521
|
+
texts.push('Cannonade damage');
|
|
522
|
+
}
|
|
523
|
+
if (!defender.hasAbility('Magic Guard') && !defender.hasType('Rock') &&
|
|
524
|
+
(field.defenderSide.volcalith || move.named('G-Max Volcalith'))) {
|
|
525
|
+
damage -= Math.floor(defender.maxHP() / 6);
|
|
526
|
+
texts.push('Volcalith damage');
|
|
527
|
+
}
|
|
528
|
+
return { damage: damage, texts: texts };
|
|
529
|
+
}
|
|
530
|
+
function computeKOChance(damage, hp, eot, hits, timesUsed, maxHP, toxicCounter) {
|
|
531
|
+
var toxicDamage = 0;
|
|
532
|
+
if (toxicCounter > 0) {
|
|
533
|
+
toxicDamage = Math.floor((toxicCounter * maxHP) / 16);
|
|
534
|
+
toxicCounter++;
|
|
535
|
+
}
|
|
536
|
+
var n = damage.length;
|
|
537
|
+
if (hits === 1) {
|
|
538
|
+
if (eot - toxicDamage > 0) {
|
|
539
|
+
eot = 0;
|
|
540
|
+
toxicDamage = 0;
|
|
541
|
+
}
|
|
542
|
+
for (var i = 0; i < n; i++) {
|
|
543
|
+
if (damage[n - 1] - eot + toxicDamage < hp)
|
|
544
|
+
return 0;
|
|
545
|
+
if (damage[i] - eot + toxicDamage >= hp) {
|
|
546
|
+
return (n - i) / n;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
var sum = 0;
|
|
551
|
+
var lastc = 0;
|
|
552
|
+
for (var i = 0; i < n; i++) {
|
|
553
|
+
var c = void 0;
|
|
554
|
+
if (i === 0 || damage[i] !== damage[i - 1]) {
|
|
555
|
+
c = computeKOChance(damage, hp - damage[i] + eot - toxicDamage, eot, hits - 1, timesUsed, maxHP, toxicCounter);
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
c = lastc;
|
|
559
|
+
}
|
|
560
|
+
if (c === 1) {
|
|
561
|
+
sum += n - i;
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
sum += c;
|
|
566
|
+
}
|
|
567
|
+
lastc = c;
|
|
568
|
+
}
|
|
569
|
+
return sum / n;
|
|
570
|
+
}
|
|
571
|
+
function predictTotal(damage, eot, hits, timesUsed, toxicCounter, maxHP) {
|
|
572
|
+
var toxicDamage = 0;
|
|
573
|
+
var lastTurnEot = eot;
|
|
574
|
+
if (toxicCounter > 0) {
|
|
575
|
+
for (var i = 0; i < hits - 1; i++) {
|
|
576
|
+
toxicDamage += Math.floor(((toxicCounter + i) * maxHP) / 16);
|
|
577
|
+
}
|
|
578
|
+
lastTurnEot -= Math.floor(((toxicCounter + (hits - 1)) * maxHP) / 16);
|
|
579
|
+
}
|
|
580
|
+
var total = 0;
|
|
581
|
+
if (hits > 1 && timesUsed === 1) {
|
|
582
|
+
total = damage * hits - eot * (hits - 1) + toxicDamage;
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
total = damage - eot * (hits - 1) + toxicDamage;
|
|
586
|
+
}
|
|
587
|
+
if (lastTurnEot < 0)
|
|
588
|
+
total -= lastTurnEot;
|
|
589
|
+
return total;
|
|
590
|
+
}
|
|
591
|
+
function squashMultihit(gen, d, hits, err) {
|
|
592
|
+
if (err === void 0) { err = true; }
|
|
593
|
+
if (d.length === 1) {
|
|
594
|
+
return [d[0] * hits];
|
|
595
|
+
}
|
|
596
|
+
else if (gen.num === 1) {
|
|
597
|
+
var r = [];
|
|
598
|
+
for (var i = 0; i < d.length; i++) {
|
|
599
|
+
r[i] = d[i] * hits;
|
|
600
|
+
}
|
|
601
|
+
return r;
|
|
602
|
+
}
|
|
603
|
+
else if (d.length === 16) {
|
|
604
|
+
switch (hits) {
|
|
605
|
+
case 2:
|
|
606
|
+
return [
|
|
607
|
+
2 * d[0], d[2] + d[3], d[4] + d[4], d[4] + d[5], d[5] + d[6], d[6] + d[6],
|
|
608
|
+
d[6] + d[7], d[7] + d[7], d[8] + d[8], d[8] + d[9], d[9] + d[9], d[9] + d[10],
|
|
609
|
+
d[10] + d[11], d[11] + d[11], d[12] + d[13], 2 * d[15],
|
|
610
|
+
];
|
|
611
|
+
case 3:
|
|
612
|
+
return [
|
|
613
|
+
3 * d[0], d[3] + d[3] + d[4], d[4] + d[4] + d[5], d[5] + d[5] + d[6],
|
|
614
|
+
d[5] + d[6] + d[6], d[6] + d[6] + d[7], d[6] + d[7] + d[7], d[7] + d[7] + d[8],
|
|
615
|
+
d[7] + d[8] + d[8], d[8] + d[8] + d[9], d[8] + d[9] + d[9], d[9] + d[9] + d[10],
|
|
616
|
+
d[9] + d[10] + d[10], d[10] + d[11] + d[11], d[11] + d[12] + d[12], 3 * d[15],
|
|
617
|
+
];
|
|
618
|
+
case 4:
|
|
619
|
+
return [
|
|
620
|
+
4 * d[0], 4 * d[4], d[4] + d[5] + d[5] + d[5], d[5] + d[5] + d[6] + d[6],
|
|
621
|
+
4 * d[6], d[6] + d[6] + d[7] + d[7], 4 * d[7], d[7] + d[7] + d[7] + d[8],
|
|
622
|
+
d[7] + d[8] + d[8] + d[8], 4 * d[8], d[8] + d[8] + d[9] + d[9], 4 * d[9],
|
|
623
|
+
d[9] + d[9] + d[10] + d[10], d[10] + d[10] + d[10] + d[11], 4 * d[11], 4 * d[15],
|
|
624
|
+
];
|
|
625
|
+
case 5:
|
|
626
|
+
return [
|
|
627
|
+
5 * d[0], d[4] + d[4] + d[4] + d[5] + d[5], d[5] + d[5] + d[5] + d[5] + d[6],
|
|
628
|
+
d[5] + d[6] + d[6] + d[6] + d[6], d[6] + d[6] + d[6] + d[6] + d[7],
|
|
629
|
+
d[6] + d[6] + d[7] + d[7] + d[7], 5 * d[7], d[7] + d[7] + d[7] + d[8] + d[8],
|
|
630
|
+
d[7] + d[7] + d[8] + d[8] + d[8], 5 * d[8], d[8] + d[8] + d[8] + d[9] + d[9],
|
|
631
|
+
d[8] + d[9] + d[9] + d[9] + d[9], d[9] + d[9] + d[9] + d[9] + d[10],
|
|
632
|
+
d[9] + d[10] + d[10] + d[10] + d[10], d[10] + d[10] + d[11] + d[11] + d[11], 5 * d[15],
|
|
633
|
+
];
|
|
634
|
+
case 10:
|
|
635
|
+
return [
|
|
636
|
+
10 * d[0], 10 * d[4], 3 * d[4] + 7 * d[5], 5 * d[5] + 5 * d[6], 10 * d[6],
|
|
637
|
+
5 * d[6] + 5 * d[7], 10 * d[7], 7 * d[7] + 3 * d[8], 3 * d[7] + 7 * d[8], 10 * d[8],
|
|
638
|
+
5 * d[8] + 5 * d[9], 4 * d[9], 5 * d[9] + 5 * d[10], 7 * d[10] + 3 * d[11], 10 * d[11],
|
|
639
|
+
10 * d[15],
|
|
640
|
+
];
|
|
641
|
+
default:
|
|
642
|
+
(0, util_1.error)(err, "Unexpected # of hits: ".concat(hits));
|
|
643
|
+
return d;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
else if (d.length === 39) {
|
|
647
|
+
switch (hits) {
|
|
648
|
+
case 2:
|
|
649
|
+
return [
|
|
650
|
+
2 * d[0], 2 * d[7], 2 * d[10], 2 * d[12], 2 * d[14], d[15] + d[16],
|
|
651
|
+
2 * d[17], d[18] + d[19], d[19] + d[20], 2 * d[21], d[22] + d[23],
|
|
652
|
+
2 * d[24], 2 * d[26], 2 * d[28], 2 * d[31], 2 * d[38],
|
|
653
|
+
];
|
|
654
|
+
case 3:
|
|
655
|
+
return [
|
|
656
|
+
3 * d[0], 3 * d[9], 3 * d[12], 3 * d[13], 3 * d[15], 3 * d[16],
|
|
657
|
+
3 * d[17], 3 * d[18], 3 * d[20], 3 * d[21], 3 * d[22], 3 * d[23],
|
|
658
|
+
3 * d[25], 3 * d[26], 3 * d[29], 3 * d[38],
|
|
659
|
+
];
|
|
660
|
+
case 4:
|
|
661
|
+
return [
|
|
662
|
+
4 * d[0], 2 * d[10] + 2 * d[11], 4 * d[13], 4 * d[14], 2 * d[15] + 2 * d[16],
|
|
663
|
+
2 * d[16] + 2 * d[17], 2 * d[17] + 2 * d[18], 2 * d[18] + 2 * d[19],
|
|
664
|
+
2 * d[19] + 2 * d[20], 2 * d[20] + 2 * d[21], 2 * d[21] + 2 * d[22],
|
|
665
|
+
2 * d[22] + 2 * d[23], 4 * d[24], 4 * d[25], 2 * d[27] + 2 * d[28], 4 * d[38],
|
|
666
|
+
];
|
|
667
|
+
case 5:
|
|
668
|
+
return [
|
|
669
|
+
5 * d[0], 5 * d[11], 5 * d[13], 5 * d[15], 5 * d[16], 5 * d[17],
|
|
670
|
+
5 * d[18], 5 * d[19], 5 * d[19], 5 * d[20], 5 * d[21], 5 * d[22],
|
|
671
|
+
5 * d[23], 5 * d[25], 5 * d[27], 5 * d[38],
|
|
672
|
+
];
|
|
673
|
+
case 10:
|
|
674
|
+
return [
|
|
675
|
+
10 * d[0], 10 * d[11], 10 * d[13], 10 * d[15], 10 * d[16], 10 * d[17],
|
|
676
|
+
10 * d[18], 10 * d[19], 10 * d[19], 10 * d[20], 10 * d[21], 10 * d[22],
|
|
677
|
+
10 * d[23], 10 * d[25], 10 * d[27], 10 * d[38],
|
|
678
|
+
];
|
|
679
|
+
default:
|
|
680
|
+
(0, util_1.error)(err, "Unexpected # of hits: ".concat(hits));
|
|
681
|
+
return d;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
else if (d.length === 256) {
|
|
685
|
+
if (hits > 1) {
|
|
686
|
+
(0, util_1.error)(err, "Unexpected # of hits for Parental Bond: ".concat(hits));
|
|
687
|
+
}
|
|
688
|
+
var r = [];
|
|
689
|
+
for (var i = 0; i < 16; i++) {
|
|
690
|
+
var val = 0;
|
|
691
|
+
for (var j = 0; j < 16; j++) {
|
|
692
|
+
val += d[i + j];
|
|
693
|
+
}
|
|
694
|
+
r[i] = Math.round(val / 16);
|
|
695
|
+
}
|
|
696
|
+
return r;
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
(0, util_1.error)(err, "Unexpected # of possible damage values: ".concat(d.length));
|
|
700
|
+
return d;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
function buildDescription(description, attacker, defender) {
|
|
704
|
+
var _a = __read(getDescriptionLevels(attacker, defender), 2), attackerLevel = _a[0], defenderLevel = _a[1];
|
|
705
|
+
var output = '';
|
|
706
|
+
if (description.attackBoost) {
|
|
707
|
+
if (description.attackBoost > 0) {
|
|
708
|
+
output += '+';
|
|
709
|
+
}
|
|
710
|
+
output += description.attackBoost + ' ';
|
|
711
|
+
}
|
|
712
|
+
output = appendIfSet(output, attackerLevel);
|
|
713
|
+
output = appendIfSet(output, description.attackEVs);
|
|
714
|
+
output = appendIfSet(output, description.attackerItem);
|
|
715
|
+
output = appendIfSet(output, description.attackerAbility);
|
|
716
|
+
output = appendIfSet(output, description.rivalry);
|
|
717
|
+
if (description.isBurned) {
|
|
718
|
+
output += 'burned ';
|
|
719
|
+
}
|
|
720
|
+
if (description.alliesFainted) {
|
|
721
|
+
output += Math.min(5, description.alliesFainted) +
|
|
722
|
+
" ".concat(description.alliesFainted === 1 ? 'ally' : 'allies', " fainted ");
|
|
723
|
+
}
|
|
724
|
+
if (description.attackerTera) {
|
|
725
|
+
output += "Tera ".concat(description.attackerTera, " ");
|
|
726
|
+
}
|
|
727
|
+
if (description.isStellarFirstUse) {
|
|
728
|
+
output += '(First Use) ';
|
|
729
|
+
}
|
|
730
|
+
if (description.isBeadsOfRuin) {
|
|
731
|
+
output += 'Beads of Ruin ';
|
|
732
|
+
}
|
|
733
|
+
if (description.isSwordOfRuin) {
|
|
734
|
+
output += 'Sword of Ruin ';
|
|
735
|
+
}
|
|
736
|
+
output += description.attackerName + ' ';
|
|
737
|
+
if (description.isHelpingHand) {
|
|
738
|
+
output += 'Helping Hand ';
|
|
739
|
+
}
|
|
740
|
+
if (description.isFlowerGiftAttacker) {
|
|
741
|
+
output += 'with an ally\'s Flower Gift ';
|
|
742
|
+
}
|
|
743
|
+
if (description.isSteelySpiritAttacker) {
|
|
744
|
+
output += 'with an ally\'s Steely Spirit ';
|
|
745
|
+
}
|
|
746
|
+
if (description.isBattery) {
|
|
747
|
+
output += 'Battery boosted ';
|
|
748
|
+
}
|
|
749
|
+
if (description.isPowerSpot) {
|
|
750
|
+
output += 'Power Spot boosted ';
|
|
751
|
+
}
|
|
752
|
+
if (description.isSwitching) {
|
|
753
|
+
output += 'switching boosted ';
|
|
754
|
+
}
|
|
755
|
+
output += description.moveName + ' ';
|
|
756
|
+
if (description.moveBP && description.moveType) {
|
|
757
|
+
output += '(' + description.moveBP + ' BP ' + description.moveType + ') ';
|
|
758
|
+
}
|
|
759
|
+
else if (description.moveBP) {
|
|
760
|
+
output += '(' + description.moveBP + ' BP) ';
|
|
761
|
+
}
|
|
762
|
+
else if (description.moveType) {
|
|
763
|
+
output += '(' + description.moveType + ') ';
|
|
764
|
+
}
|
|
765
|
+
if (description.hits) {
|
|
766
|
+
output += '(' + description.hits + ' hits) ';
|
|
767
|
+
}
|
|
768
|
+
output = appendIfSet(output, description.moveTurns);
|
|
769
|
+
output += 'vs. ';
|
|
770
|
+
if (description.defenseBoost) {
|
|
771
|
+
if (description.defenseBoost > 0) {
|
|
772
|
+
output += '+';
|
|
773
|
+
}
|
|
774
|
+
output += description.defenseBoost + ' ';
|
|
775
|
+
}
|
|
776
|
+
output = appendIfSet(output, defenderLevel);
|
|
777
|
+
output = appendIfSet(output, description.HPEVs);
|
|
778
|
+
if (description.defenseEVs) {
|
|
779
|
+
output += '/ ' + description.defenseEVs + ' ';
|
|
780
|
+
}
|
|
781
|
+
output = appendIfSet(output, description.defenderItem);
|
|
782
|
+
output = appendIfSet(output, description.defenderAbility);
|
|
783
|
+
if (description.isTabletsOfRuin) {
|
|
784
|
+
output += 'Tablets of Ruin ';
|
|
785
|
+
}
|
|
786
|
+
if (description.isVesselOfRuin) {
|
|
787
|
+
output += 'Vessel of Ruin ';
|
|
788
|
+
}
|
|
789
|
+
if (description.isProtected) {
|
|
790
|
+
output += 'protected ';
|
|
791
|
+
}
|
|
792
|
+
if (description.isDefenderDynamaxed) {
|
|
793
|
+
output += 'Dynamax ';
|
|
794
|
+
}
|
|
795
|
+
if (description.defenderTera) {
|
|
796
|
+
output += "Tera ".concat(description.defenderTera, " ");
|
|
797
|
+
}
|
|
798
|
+
output += description.defenderName;
|
|
799
|
+
if (description.weather && description.terrain) {
|
|
800
|
+
}
|
|
801
|
+
else if (description.weather) {
|
|
802
|
+
output += ' in ' + description.weather;
|
|
803
|
+
}
|
|
804
|
+
else if (description.terrain) {
|
|
805
|
+
output += ' in ' + description.terrain + ' Terrain';
|
|
806
|
+
}
|
|
807
|
+
if (description.isReflect) {
|
|
808
|
+
output += ' through Reflect';
|
|
809
|
+
}
|
|
810
|
+
else if (description.isLightScreen) {
|
|
811
|
+
output += ' through Light Screen';
|
|
812
|
+
}
|
|
813
|
+
if (description.isFlowerGiftDefender) {
|
|
814
|
+
output += ' with an ally\'s Flower Gift';
|
|
815
|
+
}
|
|
816
|
+
if (description.isFriendGuard) {
|
|
817
|
+
output += ' with an ally\'s Friend Guard';
|
|
818
|
+
}
|
|
819
|
+
if (description.isAuroraVeil) {
|
|
820
|
+
output += ' with an ally\'s Aurora Veil';
|
|
821
|
+
}
|
|
822
|
+
if (description.isCritical) {
|
|
823
|
+
output += ' on a critical hit';
|
|
824
|
+
}
|
|
825
|
+
if (description.isWonderRoom) {
|
|
826
|
+
output += ' in Wonder Room';
|
|
827
|
+
}
|
|
828
|
+
return output;
|
|
829
|
+
}
|
|
830
|
+
function getDescriptionLevels(attacker, defender) {
|
|
831
|
+
if (attacker.level !== defender.level) {
|
|
832
|
+
return [
|
|
833
|
+
attacker.level === 100 ? '' : "Lvl ".concat(attacker.level),
|
|
834
|
+
defender.level === 100 ? '' : "Lvl ".concat(defender.level),
|
|
835
|
+
];
|
|
836
|
+
}
|
|
837
|
+
var elide = [100, 50, 5].includes(attacker.level);
|
|
838
|
+
var level = elide ? '' : "Lvl ".concat(attacker.level);
|
|
839
|
+
return [level, level];
|
|
840
|
+
}
|
|
841
|
+
function serializeText(arr) {
|
|
842
|
+
if (arr.length === 0) {
|
|
843
|
+
return '';
|
|
844
|
+
}
|
|
845
|
+
else if (arr.length === 1) {
|
|
846
|
+
return arr[0];
|
|
847
|
+
}
|
|
848
|
+
else if (arr.length === 2) {
|
|
849
|
+
return arr[0] + ' and ' + arr[1];
|
|
850
|
+
}
|
|
851
|
+
else {
|
|
852
|
+
var text = '';
|
|
853
|
+
for (var i = 0; i < arr.length - 1; i++) {
|
|
854
|
+
text += arr[i] + ', ';
|
|
855
|
+
}
|
|
856
|
+
return text + 'and ' + arr[arr.length - 1];
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function appendIfSet(str, toAppend) {
|
|
860
|
+
return toAppend ? "".concat(str).concat(toAppend, " ") : str;
|
|
861
|
+
}
|
|
862
|
+
function toDisplay(notation, a, b, f) {
|
|
863
|
+
if (f === void 0) { f = 1; }
|
|
864
|
+
return notation === '%' ? Math.floor((a * (1000 / f)) / b) / 10 : Math.floor((a * (48 / f)) / b);
|
|
865
|
+
}
|
|
866
|
+
//# sourceMappingURL=desc.js.map
|