-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgens.ts
89 lines (80 loc) · 2.82 KB
/
gens.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import type {GameType, Generation, GenerationNum, Generations, Specie} from '@pkmn/data';
import {MoveOptions, PokemonOptions, State} from './state';
import {Result} from './result';
import {calculate} from './mechanics';
import * as parser from './parse';
/** Constructs a `State.Pokemon` in a specific generation `gen`. */
const pokemon = (gen: Generation) => (
name: string,
options: PokemonOptions = {},
move: string | {name?: string} = {},
) => State.createPokemon(gen, name, options, move);
/** Constructs a `State.Move` in a specific generation `gen`. */
const move = (gen: Generation) => (
name: string,
options: MoveOptions = {},
// eslint-disable-next-line @typescript-eslint/no-shadow
pokemon: string | {
species?: string | Specie;
item?: string;
ability?: string;
} = {}
) => State.createMove(gen, name, options, pokemon);
/** Performs a damage calculation in specific generation `gen`. */
interface Calculate {
(gen: Generation): (
attacker: State.Side | State.Pokemon,
defender: State.Side | State.Pokemon,
move: State.Move,
field?: State.Field,
gameType?: GameType
) => Result;
(gen: Generation): (args: string) => Result;
}
/** Parses a string into `State` in a specific generation `gen`. */
const parse = (gen: Generation) => (s: string, strict?: boolean) => parser.parse(gen, s, strict);
/** A collection of `State` factory methods and helpers scoped to a specific generation `gen`. */
export interface Scope {
gen: Generation;
calculate: Calculate;
parse: ReturnType<typeof parse>;
Pokemon: ReturnType<typeof pokemon>;
Move: ReturnType<typeof move>;
}
/** Executes a function `fn` scoped to a specific generation `gen`. */
export function inGen<T>(gen: Generation, fn: (scope: Scope) => T) {
return fn({
gen,
calculate: ((...args: any[]) => calculate(gen as any, ...args)) as unknown as Calculate,
parse: parse(gen),
Move: move(gen),
Pokemon: pokemon(gen),
});
}
/**
* Executes a function `fn` for each of the generations between `from` and `to`. If neither are
* specified `fn` is executed for every gen. If `to` is not specified it defaults to Generation 8.
*/
export function inGens(gens: Generations, fn: (scope: Scope) => void): void;
export function inGens(gens: Generations, from: GenerationNum, fn: (scope: Scope) => void): void;
export function inGens(
gens: Generations, from: GenerationNum, to: GenerationNum, fn: (scope: Scope) => void): void;
export function inGens(
gens: Generations,
from: GenerationNum | ((scope: Scope) => void),
to?: GenerationNum | ((scope: Scope) => void),
fn?: (scope: Scope) => void
) {
if (typeof from !== 'number') {
fn = fn ?? from;
from = 1;
to = 8;
}
if (typeof to !== 'number') {
fn = fn ?? to;
to = 8;
}
for (let gen = from; gen <= to; gen++) {
inGen(gens.get(gen), fn!);
}
}