-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgens.ts
113 lines (102 loc) · 3.63 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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import type {GameType, Generation, GenerationNum, Generations, Specie} from '@pkmn/data';
import {FieldOptions, MoveOptions, PokemonOptions, SideOptions, 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.Side` in a specific generation `gen`. */
const side =
(gen: Generation) =>
(sPokemon: State.Pokemon | string, sideOptions: SideOptions = {}) => {
if (typeof sPokemon === 'string') sPokemon = State.createPokemon(gen, sPokemon);
return State.createSide(gen, sPokemon, sideOptions);
};
/** Constructs a `State.Move` in a specific generation `gen`. */
const createMove =
(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);
/** Constructs a `State.Field` in a specific generation `gen`. */
const field =
(gen: Generation) =>
(options: FieldOptions = {}) =>
State.createField(gen, options);
/** 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 createMove>;
Field: ReturnType<typeof field>;
Side: ReturnType<typeof side>;
}
/** Executes a function `fn` scoped to a specific generation `gen`. */
export function inGen<T>(gen: Generation, fn: (scope: Scope) => T) {
return fn({
gen,
calculate: ((generation: Generation) => (attacker: State.Pokemon, defender: State.Pokemon, smove: State.Move) =>
calculate(generation, attacker, defender, smove)) as Calculate,
parse: parse(gen),
Move: createMove(gen),
Pokemon: pokemon(gen),
Field: field(gen),
Side: side(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!);
}
}