@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/src/state.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type * as I from './data/interface';
|
|
2
|
+
|
|
3
|
+
export namespace State {
|
|
4
|
+
export interface Pokemon {
|
|
5
|
+
name: I.SpeciesName;
|
|
6
|
+
level?: number;
|
|
7
|
+
ability?: I.AbilityName;
|
|
8
|
+
abilityOn?: boolean;
|
|
9
|
+
isDynamaxed?: boolean;
|
|
10
|
+
dynamaxLevel?: number;
|
|
11
|
+
isSaltCure?: boolean;
|
|
12
|
+
alliesFainted?: number;
|
|
13
|
+
boostedStat?: I.StatIDExceptHP | 'auto';
|
|
14
|
+
item?: I.ItemName;
|
|
15
|
+
gender?: I.GenderName;
|
|
16
|
+
nature?: I.NatureName;
|
|
17
|
+
ivs?: Partial<I.StatsTable>;
|
|
18
|
+
evs?: Partial<I.StatsTable>;
|
|
19
|
+
boosts?: Partial<I.StatsTable>;
|
|
20
|
+
originalCurHP?: number;
|
|
21
|
+
status?: I.StatusName | '';
|
|
22
|
+
teraType?: I.TypeName;
|
|
23
|
+
toxicCounter?: number;
|
|
24
|
+
moves?: I.MoveName[];
|
|
25
|
+
overrides?: Partial<I.Specie>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface Move {
|
|
29
|
+
name: I.MoveName;
|
|
30
|
+
useZ?: boolean;
|
|
31
|
+
useMax?: boolean;
|
|
32
|
+
isCrit?: boolean;
|
|
33
|
+
isStellarFirstUse?: boolean;
|
|
34
|
+
hits?: number;
|
|
35
|
+
timesUsed?: number;
|
|
36
|
+
timesUsedWithMetronome?: number;
|
|
37
|
+
overrides?: Partial<I.Move>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface Field {
|
|
41
|
+
gameType: I.GameType;
|
|
42
|
+
weather?: I.Weather;
|
|
43
|
+
terrain?: I.Terrain;
|
|
44
|
+
isMagicRoom?: boolean;
|
|
45
|
+
isWonderRoom?: boolean;
|
|
46
|
+
isGravity?: boolean;
|
|
47
|
+
isAuraBreak?: boolean;
|
|
48
|
+
isFairyAura?: boolean;
|
|
49
|
+
isDarkAura?: boolean;
|
|
50
|
+
isBeadsOfRuin?: boolean;
|
|
51
|
+
isSwordOfRuin?: boolean;
|
|
52
|
+
isTabletsOfRuin?: boolean;
|
|
53
|
+
isVesselOfRuin?: boolean;
|
|
54
|
+
attackerSide: Side;
|
|
55
|
+
defenderSide: Side;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface Side {
|
|
59
|
+
spikes?: number;
|
|
60
|
+
steelsurge?: boolean;
|
|
61
|
+
vinelash?: boolean;
|
|
62
|
+
wildfire?: boolean;
|
|
63
|
+
cannonade?: boolean;
|
|
64
|
+
volcalith?: boolean;
|
|
65
|
+
isSR?: boolean;
|
|
66
|
+
isReflect?: boolean;
|
|
67
|
+
isLightScreen?: boolean;
|
|
68
|
+
isProtected?: boolean;
|
|
69
|
+
isSeeded?: boolean;
|
|
70
|
+
isForesight?: boolean;
|
|
71
|
+
isTailwind?: boolean;
|
|
72
|
+
isHelpingHand?: boolean;
|
|
73
|
+
isFlowerGift?: boolean;
|
|
74
|
+
isFriendGuard?: boolean;
|
|
75
|
+
isAuroraVeil?: boolean;
|
|
76
|
+
isBattery?: boolean;
|
|
77
|
+
isPowerSpot?: boolean;
|
|
78
|
+
isSteelySpirit?: boolean;
|
|
79
|
+
isSwitching?: 'out' | 'in';
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/stats.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type {Natures, Generation, TypeName, StatID, StatsTable} from './data/interface';
|
|
2
|
+
import {toID} from './util';
|
|
3
|
+
|
|
4
|
+
const RBY: Array<StatID | 'spc'> = ['hp', 'atk', 'def', 'spc', 'spe'];
|
|
5
|
+
const GSC: StatID[] = ['hp', 'atk', 'def', 'spa', 'spd', 'spe'];
|
|
6
|
+
const ADV: StatID[] = GSC;
|
|
7
|
+
const DPP: StatID[] = GSC;
|
|
8
|
+
const BW: StatID[] = GSC;
|
|
9
|
+
const XY: StatID[] = GSC;
|
|
10
|
+
const SM: StatID[] = GSC;
|
|
11
|
+
const SS: StatID[] = GSC;
|
|
12
|
+
const SV: StatID[] = GSC;
|
|
13
|
+
|
|
14
|
+
export const STATS: Array<Array<StatID | 'spc'> | StatID[]> =
|
|
15
|
+
[[], RBY, GSC, ADV, DPP, BW, XY, SM, SS, SV];
|
|
16
|
+
|
|
17
|
+
type HPTypeName = Exclude<TypeName, 'Normal' | 'Fairy' | 'Stellar' | '???'>;
|
|
18
|
+
|
|
19
|
+
const HP_TYPES = [
|
|
20
|
+
'Fighting', 'Flying', 'Poison', 'Ground', 'Rock', 'Bug', 'Ghost', 'Steel',
|
|
21
|
+
'Fire', 'Water', 'Grass', 'Electric', 'Psychic', 'Ice', 'Dragon', 'Dark',
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
const HP: {[type in HPTypeName]: {ivs: Partial<StatsTable>; dvs: Partial<StatsTable>}} = {
|
|
25
|
+
Bug: {ivs: {atk: 30, def: 30, spd: 30}, dvs: {atk: 13, def: 13}},
|
|
26
|
+
Dark: {ivs: {}, dvs: {}},
|
|
27
|
+
Dragon: {ivs: {atk: 30}, dvs: {def: 14}},
|
|
28
|
+
Electric: {ivs: {spa: 30}, dvs: {atk: 14}},
|
|
29
|
+
Fighting: {ivs: {def: 30, spa: 30, spd: 30, spe: 30}, dvs: {atk: 12, def: 12}},
|
|
30
|
+
Fire: {ivs: {atk: 30, spa: 30, spe: 30}, dvs: {atk: 14, def: 12}},
|
|
31
|
+
Flying: {ivs: {hp: 30, atk: 30, def: 30, spa: 30, spd: 30}, dvs: {atk: 12, def: 13}},
|
|
32
|
+
Ghost: {ivs: {def: 30, spd: 30}, dvs: {atk: 13, def: 14}},
|
|
33
|
+
Grass: {ivs: {atk: 30, spa: 30}, dvs: {atk: 14, def: 14}},
|
|
34
|
+
Ground: {ivs: {spa: 30, spd: 30}, dvs: {atk: 12}},
|
|
35
|
+
Ice: {ivs: {atk: 30, def: 30}, dvs: {def: 13}},
|
|
36
|
+
Poison: {ivs: {def: 30, spa: 30, spd: 30}, dvs: {atk: 12, def: 14}},
|
|
37
|
+
Psychic: {ivs: {atk: 30, spe: 30}, dvs: {def: 12}},
|
|
38
|
+
Rock: {ivs: {def: 30, spd: 30, spe: 30}, dvs: {atk: 13, def: 12}},
|
|
39
|
+
Steel: {ivs: {spd: 30}, dvs: {atk: 13}},
|
|
40
|
+
Water: {ivs: {atk: 30, def: 30, spa: 30}, dvs: {atk: 14, def: 13}},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const Stats = new (class {
|
|
44
|
+
displayStat(stat: StatID | 'spc') {
|
|
45
|
+
switch (stat) {
|
|
46
|
+
case 'hp':
|
|
47
|
+
return 'HP';
|
|
48
|
+
case 'atk':
|
|
49
|
+
return 'Atk';
|
|
50
|
+
case 'def':
|
|
51
|
+
return 'Def';
|
|
52
|
+
case 'spa':
|
|
53
|
+
return 'SpA';
|
|
54
|
+
case 'spd':
|
|
55
|
+
return 'SpD';
|
|
56
|
+
case 'spe':
|
|
57
|
+
return 'Spe';
|
|
58
|
+
case 'spc':
|
|
59
|
+
return 'Spc';
|
|
60
|
+
default:
|
|
61
|
+
throw new Error(`unknown stat ${stat}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
shortForm(stat: StatID | 'spc') {
|
|
66
|
+
switch (stat) {
|
|
67
|
+
case 'hp':
|
|
68
|
+
return 'hp';
|
|
69
|
+
case 'atk':
|
|
70
|
+
return 'at';
|
|
71
|
+
case 'def':
|
|
72
|
+
return 'df';
|
|
73
|
+
case 'spa':
|
|
74
|
+
return 'sa';
|
|
75
|
+
case 'spd':
|
|
76
|
+
return 'sd';
|
|
77
|
+
case 'spe':
|
|
78
|
+
return 'sp';
|
|
79
|
+
case 'spc':
|
|
80
|
+
return 'sl';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
getHPDV(ivs: {atk: number; def: number; spe: number; spc: number}) {
|
|
85
|
+
return (
|
|
86
|
+
(this.IVToDV(ivs.atk) % 2) * 8 +
|
|
87
|
+
(this.IVToDV(ivs.def) % 2) * 4 +
|
|
88
|
+
(this.IVToDV(ivs.spe) % 2) * 2 +
|
|
89
|
+
(this.IVToDV(ivs.spc) % 2)
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
IVToDV(iv: number) {
|
|
94
|
+
return Math.floor(iv / 2);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
DVToIV(dv: number) {
|
|
98
|
+
return dv * 2;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
DVsToIVs(dvs: Readonly<Partial<StatsTable>>) {
|
|
102
|
+
const ivs: Partial<StatsTable> = {};
|
|
103
|
+
let dv: StatID;
|
|
104
|
+
for (dv in dvs) {
|
|
105
|
+
ivs[dv] = Stats.DVToIV(dvs[dv]!);
|
|
106
|
+
}
|
|
107
|
+
return ivs;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
calcStat(
|
|
111
|
+
gen: Generation,
|
|
112
|
+
stat: StatID,
|
|
113
|
+
base: number,
|
|
114
|
+
iv: number,
|
|
115
|
+
ev: number,
|
|
116
|
+
level: number,
|
|
117
|
+
nature?: string
|
|
118
|
+
) {
|
|
119
|
+
if (gen.num < 1 || gen.num > 9) throw new Error(`Invalid generation ${gen.num}`);
|
|
120
|
+
if (gen.num < 3) return this.calcStatRBY(stat, base, iv, level);
|
|
121
|
+
return this.calcStatADV(gen.natures, stat, base, iv, ev, level, nature);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
calcStatADV(
|
|
125
|
+
natures: Natures,
|
|
126
|
+
stat: StatID,
|
|
127
|
+
base: number,
|
|
128
|
+
iv: number,
|
|
129
|
+
ev: number,
|
|
130
|
+
level: number,
|
|
131
|
+
nature?: string
|
|
132
|
+
) {
|
|
133
|
+
if (stat === 'hp') {
|
|
134
|
+
return base === 1
|
|
135
|
+
? base
|
|
136
|
+
: Math.floor(((base * 2 + iv + Math.floor(ev / 4)) * level) / 100) + level + 10;
|
|
137
|
+
} else {
|
|
138
|
+
let mods: [StatID?, StatID?] = [undefined, undefined];
|
|
139
|
+
if (nature) {
|
|
140
|
+
const nat = natures.get(toID(nature));
|
|
141
|
+
mods = [nat?.plus, nat?.minus];
|
|
142
|
+
}
|
|
143
|
+
const n =
|
|
144
|
+
mods[0] === stat && mods[1] === stat
|
|
145
|
+
? 1
|
|
146
|
+
: mods[0] === stat
|
|
147
|
+
? 1.1
|
|
148
|
+
: mods[1] === stat
|
|
149
|
+
? 0.9
|
|
150
|
+
: 1;
|
|
151
|
+
|
|
152
|
+
return Math.floor((Math.floor(((base * 2 + iv + Math.floor(ev / 4)) * level) / 100) + 5) * n);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
calcStatRBY(stat: StatID, base: number, iv: number, level: number) {
|
|
157
|
+
return this.calcStatRBYFromDV(stat, base, this.IVToDV(iv), level);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
calcStatRBYFromDV(stat: StatID, base: number, dv: number, level: number) {
|
|
161
|
+
if (stat === 'hp') {
|
|
162
|
+
return Math.floor((((base + dv) * 2 + 63) * level) / 100) + level + 10;
|
|
163
|
+
} else {
|
|
164
|
+
return Math.floor((((base + dv) * 2 + 63) * level) / 100) + 5;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
getHiddenPowerIVs(gen: Generation, hpType: HPTypeName) {
|
|
169
|
+
const hp = HP[hpType];
|
|
170
|
+
if (!hp) return undefined;
|
|
171
|
+
return gen.num === 2 ? Stats.DVsToIVs(hp.dvs) : hp.ivs;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
getHiddenPower(gen: Generation, ivs: StatsTable) {
|
|
175
|
+
const tr = (num: number, bits = 0) => {
|
|
176
|
+
if (bits) return (num >>> 0) % (2 ** bits);
|
|
177
|
+
return num >>> 0;
|
|
178
|
+
};
|
|
179
|
+
const stats = {hp: 31, atk: 31, def: 31, spe: 31, spa: 31, spd: 31};
|
|
180
|
+
if (gen.num <= 2) {
|
|
181
|
+
// Gen 2 specific Hidden Power check. IVs are still treated 0-31 so we get them 0-15
|
|
182
|
+
const atkDV = tr(ivs.atk / 2);
|
|
183
|
+
const defDV = tr(ivs.def / 2);
|
|
184
|
+
const speDV = tr(ivs.spe / 2);
|
|
185
|
+
const spcDV = tr(ivs.spa / 2);
|
|
186
|
+
return {
|
|
187
|
+
type: HP_TYPES[4 * (atkDV % 4) + (defDV % 4)] as TypeName,
|
|
188
|
+
power: tr(
|
|
189
|
+
(5 * ((spcDV >> 3) +
|
|
190
|
+
(2 * (speDV >> 3)) +
|
|
191
|
+
(4 * (defDV >> 3)) +
|
|
192
|
+
(8 * (atkDV >> 3))) +
|
|
193
|
+
(spcDV % 4)) / 2 + 31
|
|
194
|
+
),
|
|
195
|
+
};
|
|
196
|
+
} else {
|
|
197
|
+
// Hidden Power check for Gen 3 onwards
|
|
198
|
+
let hpTypeX = 0;
|
|
199
|
+
let hpPowerX = 0;
|
|
200
|
+
let i = 1;
|
|
201
|
+
for (const s in stats) {
|
|
202
|
+
hpTypeX += i * (ivs[s as StatID] % 2);
|
|
203
|
+
hpPowerX += i * (tr(ivs[s as StatID] / 2) % 2);
|
|
204
|
+
i *= 2;
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
type: HP_TYPES[tr(hpTypeX * 15 / 63)] as TypeName,
|
|
208
|
+
// After Gen 6, Hidden Power is always 60 base power
|
|
209
|
+
power: (gen.num && gen.num < 6) ? tr(hpPowerX * 40 / 63) + 30 : 60,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
})();
|