@pkmn/engine 0.1.0-dev.2c13d3ec → 0.1.0-dev.305a932f
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/README.md +45 -37
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/protocol.json +69 -12
- package/build/pkg/data.d.ts +2 -2
- package/build/pkg/protocol.js +56 -37
- package/build/pkg/protocol.js.map +1 -1
- package/build.zig +53 -44
- package/package.json +33 -15
- package/src/bin/install-pkmn-engine +2 -2
- package/src/lib/binding/node.zig +1 -1
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +4 -16
- package/src/lib/common/js.zig +118 -0
- package/src/lib/common/optional.zig +60 -0
- package/src/lib/common/protocol.zig +520 -66
- package/src/lib/common/rational.zig +353 -0
- package/src/lib/common/rng.zig +6 -6
- package/src/lib/common/util.zig +12 -0
- package/src/lib/gen1/README.md +246 -166
- package/src/lib/gen1/calc.zig +426 -0
- package/src/lib/gen1/chance.zig +1058 -0
- package/src/lib/gen1/data/moves.zig +168 -170
- package/src/lib/gen1/data/types.zig +2 -2
- package/src/lib/gen1/data.zig +25 -32
- package/src/lib/gen1/helpers.zig +240 -87
- package/src/lib/gen1/mechanics.zig +50 -72
- package/src/lib/gen2/README.md +106 -85
- package/src/lib/gen2/data/items.zig +10 -16
- package/src/lib/gen2/data/moves.zig +639 -562
- package/src/lib/gen2/data/types.zig +81 -25
- package/src/lib/gen2/data.zig +78 -63
- package/src/lib/gen2/helpers.zig +8 -12
- package/src/lib/gen2/mechanics.zig +1237 -7
package/README.md
CHANGED
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
<img alt="License" src="https://img.shields.io/badge/License-MIT-blue.svg" />
|
|
13
13
|
</a>
|
|
14
14
|
</p>
|
|
15
|
+
|
|
16
|
+
> [!WARNING]
|
|
17
|
+
> **This project is under heavy development** and currently the `main` branch contains numerous breaking
|
|
18
|
+
> changes which may not work and which are not fully documented. Please **wait for the forthcoming
|
|
19
|
+
> initial v0.1 release** before depending on this project (code from the
|
|
20
|
+
> [`old`](https://github.com/pkmn/engine/releases/tag/old) tag can also be used to experiment with a
|
|
21
|
+
> more stable version of the codebase).
|
|
22
|
+
|
|
15
23
|
<hr />
|
|
16
24
|
|
|
17
25
|
A minimal, complete, Pokémon battle simulation engine optimized for performance and
|
|
@@ -49,9 +57,9 @@ $ zig build --prefix /usr/local -Doptimize=ReleaseFast
|
|
|
49
57
|
```
|
|
50
58
|
|
|
51
59
|
The Zig website has [installation instructions](https://ziglang.org/learn/getting-started/) which
|
|
52
|
-
walk through how to install Zig on each platform - the engine code should work on Zig v0.11.0
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
walk through how to install Zig on each platform - the engine code should work on Zig v0.11.0 or
|
|
61
|
+
greater, though tracks Zig's master branch so this may change in the future if breaking language
|
|
62
|
+
changes are introduced.
|
|
55
63
|
|
|
56
64
|
`libpkmn` can be built with `-Dshowdown` to instead produce the Pokémon Showdown compatible
|
|
57
65
|
`libpkmn-showdown` library. Furthermore, protocol message logging can be enabled through `-Dlog`.
|
|
@@ -67,12 +75,12 @@ $ npm install @pkmn/engine
|
|
|
67
75
|
```
|
|
68
76
|
|
|
69
77
|
The driver depends on being able to find compiled Node/WASM addons in
|
|
70
|
-
`node_modules/@pkmn/engine/build/lib`
|
|
71
|
-
|
|
72
|
-
[`install-pkmn-engine`](src/bin/install-pkmn-engine) which
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
`node_modules/@pkmn/engine/build/lib` to be useful. When you install the package a [`postinstall`
|
|
79
|
+
lifecycle script](https://docs.npmjs.com/cli/v8/using-npm/scripts) runs
|
|
80
|
+
[`install-pkmn-engine`](src/bin/install-pkmn-engine) which checks for a compatible `zig` compiler
|
|
81
|
+
(see earlier regarding minimum version) and download one to `node_module/@pkmn/engine/build/bin` if
|
|
82
|
+
it can't find one, as well as looking for (and downloading, if necessary) the required Node headers
|
|
83
|
+
needed to successfully build the addons natively.
|
|
76
84
|
|
|
77
85
|
**If you have configured `npm` to `--ignore-scripts` you must either run `npx install-pkmn-engine`
|
|
78
86
|
directly or build the addons manually and place the artifacts in the expected paths.**
|
|
@@ -100,7 +108,7 @@ configuring whether or not Pokémon Showdown compatibility mode or protocol mess
|
|
|
100
108
|
enabled. Alternatively, you may set options via a `pkmn_options` [root source file
|
|
101
109
|
declaration](https://ziglang.org/documentation/master/#Root-Source-File). There are several
|
|
102
110
|
undocumented internal options that can be tweaked as well via build or root options, though these
|
|
103
|
-
options
|
|
111
|
+
options aren't officially supported, affect correctness, and may change meaning or behavior without
|
|
104
112
|
warning. Use at your own risk.
|
|
105
113
|
|
|
106
114
|
```zig
|
|
@@ -112,11 +120,11 @@ pub const pkmn_options = .{ .showdown = true, .log = true };
|
|
|
112
120
|
For each Pokémon generation, the engine provides a battle structure with two functions - a function
|
|
113
121
|
to `update` the battle's state based on both players' choices and a function that defines which
|
|
114
122
|
`choices` are valid at that decision point (at the beginning of a battle both player's must "pass"
|
|
115
|
-
as their first choice
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
as their first choice to switch in the first member of their party). If `-Dlog` protocol logging is
|
|
124
|
+
enabled each update produces logs which can be decoded into a buffer (`LOGS_SIZE` constants are
|
|
125
|
+
provided to make it easy to allocate a buffer of the correct size). Each `update` returns a result
|
|
126
|
+
to indicate either that the battle has terminated or which types of choices are available for each
|
|
127
|
+
player.
|
|
120
128
|
|
|
121
129
|
Unlike [Pokémon Showdown's
|
|
122
130
|
SIM-PROTOCOL](https://github.com/smogon/pokemon-showdown/blob/master/sim/SIM-PROTOCOL.md#choice-requests)
|
|
@@ -128,7 +136,7 @@ state or cause the engine to crash.**
|
|
|
128
136
|
|
|
129
137
|
Battles may be played out from any point but to freshly initialize a battle which is yet to start
|
|
130
138
|
the turn count and active Pokémon should be zeroed out (driver code should handle this for you).
|
|
131
|
-
Most driver code should also provide helpers to make
|
|
139
|
+
Most driver code should also provide helpers to make initializing battle convenient - check the
|
|
132
140
|
respective documentation and examples for the bindings being used. The engine's [protocol
|
|
133
141
|
documentation](docs/PROTOCOL.md) goes into greater detail on the specifics of updates and the
|
|
134
142
|
potential logs that may result.
|
|
@@ -140,7 +148,7 @@ potential logs that may result.
|
|
|
140
148
|
|
|
141
149
|
[`pkmn.h`](src/include/pkmn.h) exports the C API for `libpkmn`. Symbols are all prefixed with
|
|
142
150
|
`pkmn_` to avoid name collisions. If `-Dlog` is enabled and logging throws an error then the error
|
|
143
|
-
|
|
151
|
+
is encoded in the `pkmn_result` and can be checked with `pkmn_error`.
|
|
144
152
|
|
|
145
153
|
```c
|
|
146
154
|
#include <pkmn.h>
|
|
@@ -161,17 +169,17 @@ if (pkmn_error(result)) exit(1);
|
|
|
161
169
|
|
|
162
170
|
[(full code)](src/examples/c/example.c)
|
|
163
171
|
|
|
164
|
-
The C API
|
|
172
|
+
The C API doesn't export any helpers for creating or accessing the opaque battle objects - it's
|
|
165
173
|
instead intended to be used as the foundation for more ergonomic bindings in [other
|
|
166
174
|
languages](#other) (the lack of namespaces and bit fields having an implementation-defined layout in
|
|
167
175
|
C are the main contributing factors to the sparseness of what `libpkmn` chooses to expose).
|
|
168
176
|
|
|
169
177
|
### JavaScript / TypeScript
|
|
170
178
|
|
|
171
|
-
`@pkmn/engine` depends on the [`@pkmn/data`](https://www.npmjs.com/package/@pkmn/data) which
|
|
179
|
+
`@pkmn/engine` depends on the [`@pkmn/data`](https://www.npmjs.com/package/@pkmn/data) package which
|
|
172
180
|
requires a `Dex` implementation to be provided as well. The `Battle.create` function can be used to
|
|
173
181
|
initialize a `Battle` from the beginning, or `Battle.restore` can be used to re-instantiate a battle
|
|
174
|
-
which is in
|
|
182
|
+
which is already in progress. If logging is enabled the output can be turned into Pokémon Showdown
|
|
175
183
|
protocol via `Log.parse`.
|
|
176
184
|
|
|
177
185
|
```ts
|
|
@@ -196,18 +204,18 @@ console.log(result);
|
|
|
196
204
|
|
|
197
205
|
[(full code)](src/examples/js/example.ts)
|
|
198
206
|
|
|
199
|
-
By default, the `@pkmn/engine` package
|
|
207
|
+
By default, the `@pkmn/engine` package compiles the engine with `-Dshowdown`, though by running
|
|
200
208
|
`install-pkmn-engine` directly and passing in `--options` you can override this default and build
|
|
201
209
|
different configurations of the extension for the driver to use. The driver can support
|
|
202
210
|
configurations both with and without Pokémon Showdown compatibility simultaneously if present. On
|
|
203
|
-
update, the post-install script
|
|
211
|
+
update, the post-install script attempts to rebuild whichever extensions it finds with the same
|
|
204
212
|
configuration parameters that were originally used meaning updating to the newest version of the
|
|
205
213
|
library should be seamless.
|
|
206
214
|
|
|
207
215
|
Despite relying on the native engine code, the `@pkmn/engine` code is designed to also work in
|
|
208
216
|
browsers which support [WebAssembly](https://webassembly.org/). Running `npm run start:web` from the
|
|
209
|
-
[`examples`](src/examples/js) directory
|
|
210
|
-
|
|
217
|
+
[`examples`](src/examples/js) directory starts a server that can be used to demonstrate the engine
|
|
218
|
+
running in the browser.
|
|
211
219
|
|
|
212
220
|
### Zig
|
|
213
221
|
|
|
@@ -240,7 +248,7 @@ std.debug.print("{}\n", .{result.type});
|
|
|
240
248
|
|
|
241
249
|
The Zig package also supports some APIs which are difficult to expose elsewhere such as the
|
|
242
250
|
`FixedRNG` which allows you to fully specify the exact RNG frames (which can be useful for ensuring
|
|
243
|
-
certain outcomes/effects always occur) for a battle, though doing so
|
|
251
|
+
certain outcomes/effects always occur) for a battle, though doing so changes the size of the
|
|
244
252
|
`Battle` object.
|
|
245
253
|
|
|
246
254
|
### Other
|
|
@@ -251,7 +259,7 @@ simplify the process even further [`src/data`](src/data) contains JSON dumps of
|
|
|
251
259
|
data, structure sizes and offsets, and protocol information used by the reference driver code. The
|
|
252
260
|
following is a list of known `libpkmn` bindings written by developers outside of the [pkmn
|
|
253
261
|
organization](https://github.com/pkmn) that may be helpful (though note that these projects may not
|
|
254
|
-
necessarily be up-to-date/complete/correct - inclusion in this list
|
|
262
|
+
necessarily be up-to-date/complete/correct - inclusion in this list doesn't imply endorsement):
|
|
255
263
|
|
|
256
264
|
| Language | License | URL |
|
|
257
265
|
| ---------- | --------- | ------------------------------------ |
|
|
@@ -279,7 +287,7 @@ By default, `pkmn-debug` expects to read [binary debug protocol](docs/PROTOCOL.m
|
|
|
279
287
|
$ <cmd> | pkmn-debug > index.html
|
|
280
288
|
```
|
|
281
289
|
|
|
282
|
-
Alternatively, if a single filename argument is passed to the `pkmn-debug` it
|
|
290
|
+
Alternatively, if a single filename argument is passed to the `pkmn-debug` it reads from that
|
|
283
291
|
instead:
|
|
284
292
|
|
|
285
293
|
```sh
|
|
@@ -301,14 +309,14 @@ Currently, most of the foundational work from stage 0 is done:
|
|
|
301
309
|
|
|
302
310
|
- [benchmark and integration testing](src/test) infrastructure
|
|
303
311
|
- [documentation](docs) about design, research, methodology, etc
|
|
304
|
-
- definition and implementation of the [protocol](docs/PROTOCOL.md) that
|
|
312
|
+
- definition and implementation of the [protocol](docs/PROTOCOL.md) that's used by the engine
|
|
305
313
|
|
|
306
|
-
**Stage 1 is currently in progress** and
|
|
314
|
+
**Stage 1 is currently in progress** and involves the implementation of the actual Generation I & II
|
|
307
315
|
battle engines, followed by Generation III & IV in stage 2. The implementation of further Pokémon
|
|
308
|
-
generations is in scope for the project but
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
316
|
+
generations is in scope for the project but shouldn't be considered part of the immediate roadmap
|
|
317
|
+
(i.e. exploring the options for broadening support for old generation APIs is given higher priority
|
|
318
|
+
than implementing more modern generations). Furthermore, implementation of modern generations is
|
|
319
|
+
soft-blocked on the [availability of high quality
|
|
312
320
|
decompilations](https://github.com/orgs/pret/repositories) of the original games in question.
|
|
313
321
|
|
|
314
322
|
Certain features will always be deemed **out of scope**:
|
|
@@ -326,10 +334,10 @@ The pkmn engine is distributed under the terms of the [MIT License](LICENSE).
|
|
|
326
334
|
[^1]: In the case of Pokémon Showdown, only bugs which stem from a misimplementation of specific
|
|
327
335
|
effects are reproduced in the engine, bugs which are the result of a misunderstanding of the
|
|
328
336
|
fundamental mechanics of Pokémon or which simply arise due to specific Pokémon Showdown
|
|
329
|
-
implementation details that
|
|
330
|
-
choices
|
|
337
|
+
implementation details that aren't replicable without making the same (incorrect) architectural
|
|
338
|
+
choices aren't. Furthermore, the "Pokémon Showdown" code referenced by this project includes
|
|
331
339
|
several [patches](docs/TESTING.md#patches) to improve accuracy and smooth over some of the more
|
|
332
340
|
egregious implementation issues. In practical terms, the vast majority of games played out in the
|
|
333
|
-
pkmn engine's compatibility mode and on this patched Pokémon Showdown simulator
|
|
334
|
-
it
|
|
341
|
+
pkmn engine's compatibility mode and on this patched Pokémon Showdown simulator are the same,
|
|
342
|
+
it's only in a well defined and documented set of circumstances where the two implementations
|
|
335
343
|
diverge.
|
package/build/pkg/data/ids.json
CHANGED
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"types": [
|
|
23
|
+
"Ground",
|
|
24
|
+
"Rock",
|
|
25
|
+
"Steel",
|
|
23
26
|
"Normal",
|
|
24
27
|
"Fighting",
|
|
25
28
|
"Flying",
|
|
26
29
|
"Poison",
|
|
27
|
-
"Ground",
|
|
28
|
-
"Rock",
|
|
29
30
|
"Bug",
|
|
30
31
|
"Ghost",
|
|
31
|
-
"Steel",
|
|
32
32
|
"???",
|
|
33
33
|
"Fire",
|
|
34
34
|
"Water",
|
|
@@ -40,15 +40,15 @@
|
|
|
40
40
|
"Dark"
|
|
41
41
|
],
|
|
42
42
|
"items": [
|
|
43
|
+
"softsand",
|
|
44
|
+
"hardstone",
|
|
45
|
+
"metalcoat",
|
|
43
46
|
"pinkbow",
|
|
44
47
|
"blackbelt",
|
|
45
48
|
"sharpbeak",
|
|
46
49
|
"poisonbarb",
|
|
47
|
-
"softsand",
|
|
48
|
-
"hardstone",
|
|
49
50
|
"silverpowder",
|
|
50
51
|
"spelltag",
|
|
51
|
-
"metalcoat",
|
|
52
52
|
"polkadotbow",
|
|
53
53
|
"charcoal",
|
|
54
54
|
"mysticwater",
|
|
@@ -65,21 +65,21 @@
|
|
|
65
65
|
"stick",
|
|
66
66
|
"thickclub",
|
|
67
67
|
"focusband",
|
|
68
|
-
"berryjuice",
|
|
69
68
|
"scopelens",
|
|
70
69
|
"leftovers",
|
|
71
70
|
"berserkgene",
|
|
72
71
|
"lightball",
|
|
72
|
+
"berry",
|
|
73
|
+
"berryjuice",
|
|
74
|
+
"goldberry",
|
|
75
|
+
"mintberry",
|
|
73
76
|
"psncureberry",
|
|
74
77
|
"przcureberry",
|
|
75
|
-
"burntberry",
|
|
76
78
|
"iceberry",
|
|
77
|
-
"
|
|
78
|
-
"mintberry",
|
|
79
|
+
"burntberry",
|
|
79
80
|
"miracleberry",
|
|
81
|
+
"bitterberry",
|
|
80
82
|
"mysteryberry",
|
|
81
|
-
"berry",
|
|
82
|
-
"goldberry",
|
|
83
83
|
"masterball",
|
|
84
84
|
"ultraball",
|
|
85
85
|
"greatball",
|
|
@@ -70,7 +70,8 @@
|
|
|
70
70
|
"Burst",
|
|
71
71
|
"ClearPositiveBoost",
|
|
72
72
|
"CanDynamax",
|
|
73
|
-
"SwapSideConditions"
|
|
73
|
+
"SwapSideConditions",
|
|
74
|
+
"Terastallize"
|
|
74
75
|
],
|
|
75
76
|
"Move": [
|
|
76
77
|
"None",
|
|
@@ -84,12 +85,14 @@
|
|
|
84
85
|
"Flinch",
|
|
85
86
|
"Disable",
|
|
86
87
|
"Recharge",
|
|
87
|
-
"PP"
|
|
88
|
+
"PP",
|
|
89
|
+
"Attract"
|
|
88
90
|
],
|
|
89
91
|
"Heal": [
|
|
90
92
|
"None",
|
|
91
93
|
"Silent",
|
|
92
|
-
"Drain"
|
|
94
|
+
"Drain",
|
|
95
|
+
"Leftovers"
|
|
93
96
|
],
|
|
94
97
|
"Damage": [
|
|
95
98
|
"None",
|
|
@@ -97,7 +100,13 @@
|
|
|
97
100
|
"Burn",
|
|
98
101
|
"Confusion",
|
|
99
102
|
"LeechSeed",
|
|
100
|
-
"RecoilOf"
|
|
103
|
+
"RecoilOf",
|
|
104
|
+
"Bind",
|
|
105
|
+
"Wrap",
|
|
106
|
+
"FireSpin",
|
|
107
|
+
"Clamp",
|
|
108
|
+
"Whirlpool",
|
|
109
|
+
"Spikes"
|
|
101
110
|
],
|
|
102
111
|
"Status": [
|
|
103
112
|
"None",
|
|
@@ -136,7 +145,15 @@
|
|
|
136
145
|
"Mist",
|
|
137
146
|
"Struggle",
|
|
138
147
|
"Substitute",
|
|
139
|
-
"Splash"
|
|
148
|
+
"Splash",
|
|
149
|
+
"Attract",
|
|
150
|
+
"LockOn",
|
|
151
|
+
"Bind",
|
|
152
|
+
"Wrap",
|
|
153
|
+
"FireSpin",
|
|
154
|
+
"Clamp",
|
|
155
|
+
"Whirlpool",
|
|
156
|
+
"BeatUp"
|
|
140
157
|
],
|
|
141
158
|
"Start": [
|
|
142
159
|
"Bide",
|
|
@@ -150,24 +167,64 @@
|
|
|
150
167
|
"Substitute",
|
|
151
168
|
"TypeChange",
|
|
152
169
|
"Disable",
|
|
153
|
-
"Mimic"
|
|
170
|
+
"Mimic",
|
|
171
|
+
"Nightmare",
|
|
172
|
+
"Curse",
|
|
173
|
+
"Foresight",
|
|
174
|
+
"Encore",
|
|
175
|
+
"FutureSight",
|
|
176
|
+
"PerishSong3Silent",
|
|
177
|
+
"PerishSong3",
|
|
178
|
+
"PerishSong2",
|
|
179
|
+
"PerishSong1",
|
|
180
|
+
"PerishSong0"
|
|
154
181
|
],
|
|
155
182
|
"End": [
|
|
156
183
|
"Disable",
|
|
157
184
|
"Confusion",
|
|
158
185
|
"Bide",
|
|
159
186
|
"Substitute",
|
|
187
|
+
"Nightmare",
|
|
188
|
+
"Curse",
|
|
189
|
+
"Foresight",
|
|
190
|
+
"Encore",
|
|
191
|
+
"FutureSight",
|
|
192
|
+
"LeechSeed",
|
|
193
|
+
"Bind",
|
|
194
|
+
"Wrap",
|
|
195
|
+
"FireSpin",
|
|
196
|
+
"Clamp",
|
|
197
|
+
"Whirlpool",
|
|
160
198
|
"DisableSilent",
|
|
161
199
|
"ConfusionSilent",
|
|
162
|
-
"
|
|
163
|
-
"
|
|
164
|
-
"
|
|
165
|
-
"
|
|
166
|
-
"
|
|
167
|
-
"
|
|
200
|
+
"MistSilent",
|
|
201
|
+
"FocusEnergySilent",
|
|
202
|
+
"LeechSeedSilent",
|
|
203
|
+
"ToxicSilent",
|
|
204
|
+
"LightScreenSilent",
|
|
205
|
+
"ReflectSilent",
|
|
206
|
+
"BideSilent"
|
|
168
207
|
],
|
|
169
208
|
"Immune": [
|
|
170
209
|
"None",
|
|
171
210
|
"OHKO"
|
|
211
|
+
],
|
|
212
|
+
"EndItem": [
|
|
213
|
+
"None",
|
|
214
|
+
"Eat"
|
|
215
|
+
],
|
|
216
|
+
"SetHP": [
|
|
217
|
+
"None",
|
|
218
|
+
"Silent"
|
|
219
|
+
],
|
|
220
|
+
"Side": [
|
|
221
|
+
"Safeguard",
|
|
222
|
+
"Reflect",
|
|
223
|
+
"LightScreen",
|
|
224
|
+
"Spikes"
|
|
225
|
+
],
|
|
226
|
+
"Weather": [
|
|
227
|
+
"None",
|
|
228
|
+
"Upkeep"
|
|
172
229
|
]
|
|
173
230
|
}
|
package/build/pkg/data.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { Generation, ID, TypeName } from '@pkmn/data';
|
|
|
2
2
|
export declare const LE: boolean;
|
|
3
3
|
export type IDs = [
|
|
4
4
|
{
|
|
5
|
-
types: TypeName[];
|
|
5
|
+
types: Exclude<TypeName, 'Dark' | 'Steel' | 'Fairy'>[];
|
|
6
6
|
},
|
|
7
7
|
{
|
|
8
8
|
items: ID[];
|
|
9
|
-
types: TypeName[];
|
|
9
|
+
types: Exclude<TypeName, 'Fairy'>[];
|
|
10
10
|
}
|
|
11
11
|
];
|
|
12
12
|
export declare const IDS: IDs;
|
package/build/pkg/protocol.js
CHANGED
|
@@ -99,6 +99,7 @@ class Log {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
exports.Log = Log;
|
|
102
|
+
const GENDERS = ['M', 'F', 'N'];
|
|
102
103
|
const CANT = new Array(data_1.PROTOCOL.Cant.length);
|
|
103
104
|
CANT[data_1.PROTOCOL.Cant.Sleep] = 'slp';
|
|
104
105
|
CANT[data_1.PROTOCOL.Cant.Freeze] = 'frz';
|
|
@@ -129,37 +130,51 @@ FAIL[data_1.PROTOCOL.Fail.Burn] = 'brn';
|
|
|
129
130
|
FAIL[data_1.PROTOCOL.Fail.Freeze] = 'frz';
|
|
130
131
|
FAIL[data_1.PROTOCOL.Fail.Paralysis] = 'par';
|
|
131
132
|
FAIL[data_1.PROTOCOL.Fail.Toxic] = 'tox';
|
|
132
|
-
const ACTIVATE = new Array(data_1.PROTOCOL.Activate.length);
|
|
133
|
-
ACTIVATE[data_1.PROTOCOL.Activate.Bide] = 'Bide';
|
|
134
|
-
ACTIVATE[data_1.PROTOCOL.Activate.Confusion] = 'confusion';
|
|
135
|
-
ACTIVATE[data_1.PROTOCOL.Activate.Haze] = 'move: Haze';
|
|
136
|
-
ACTIVATE[data_1.PROTOCOL.Activate.Mist] = 'move: Mist';
|
|
137
|
-
ACTIVATE[data_1.PROTOCOL.Activate.Struggle] = 'move: Struggle';
|
|
138
|
-
ACTIVATE[data_1.PROTOCOL.Activate.Substitute] = 'Substitute';
|
|
139
|
-
ACTIVATE[data_1.PROTOCOL.Activate.Splash] = 'move: Splash';
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
START[data_1.PROTOCOL.Start.
|
|
143
|
-
START[data_1.PROTOCOL.Start.
|
|
144
|
-
START[data_1.PROTOCOL.Start.
|
|
145
|
-
START[data_1.PROTOCOL.Start.
|
|
146
|
-
START[data_1.PROTOCOL.Start.
|
|
147
|
-
START[data_1.PROTOCOL.Start.
|
|
148
|
-
START[data_1.PROTOCOL.Start.
|
|
149
|
-
START[data_1.PROTOCOL.Start.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
END[data_1.PROTOCOL.End.
|
|
155
|
-
END[data_1.PROTOCOL.End.
|
|
156
|
-
END[data_1.PROTOCOL.End.
|
|
157
|
-
END[data_1.PROTOCOL.End.
|
|
158
|
-
END[data_1.PROTOCOL.End.
|
|
159
|
-
END[data_1.PROTOCOL.End.
|
|
160
|
-
END[data_1.PROTOCOL.End.
|
|
161
|
-
END[data_1.PROTOCOL.End.
|
|
162
|
-
END[data_1.PROTOCOL.End.
|
|
133
|
+
const ACTIVATE = [new Array(data_1.PROTOCOL.Activate.length)];
|
|
134
|
+
ACTIVATE[0][data_1.PROTOCOL.Activate.Bide] = 'Bide';
|
|
135
|
+
ACTIVATE[0][data_1.PROTOCOL.Activate.Confusion] = 'confusion';
|
|
136
|
+
ACTIVATE[0][data_1.PROTOCOL.Activate.Haze] = 'move: Haze';
|
|
137
|
+
ACTIVATE[0][data_1.PROTOCOL.Activate.Mist] = 'move: Mist';
|
|
138
|
+
ACTIVATE[0][data_1.PROTOCOL.Activate.Struggle] = 'move: Struggle';
|
|
139
|
+
ACTIVATE[0][data_1.PROTOCOL.Activate.Substitute] = 'Substitute';
|
|
140
|
+
ACTIVATE[0][data_1.PROTOCOL.Activate.Splash] = 'move: Splash';
|
|
141
|
+
ACTIVATE[1] = ACTIVATE[0].slice(0);
|
|
142
|
+
ACTIVATE[1][data_1.PROTOCOL.Activate.Bide] = 'move: Bide';
|
|
143
|
+
const START = [new Array(data_1.PROTOCOL.Start.length)];
|
|
144
|
+
START[0][data_1.PROTOCOL.Start.Bide] = 'Bide';
|
|
145
|
+
START[0][data_1.PROTOCOL.Start.Confusion] = 'confusion';
|
|
146
|
+
START[0][data_1.PROTOCOL.Start.ConfusionSilent] = 'confusion';
|
|
147
|
+
START[0][data_1.PROTOCOL.Start.FocusEnergy] = 'move: Focus Energy';
|
|
148
|
+
START[0][data_1.PROTOCOL.Start.LeechSeed] = 'move: Leech Seed';
|
|
149
|
+
START[0][data_1.PROTOCOL.Start.LightScreen] = 'Light Screen';
|
|
150
|
+
START[0][data_1.PROTOCOL.Start.Mist] = 'Mist';
|
|
151
|
+
START[0][data_1.PROTOCOL.Start.Reflect] = 'Reflect';
|
|
152
|
+
START[0][data_1.PROTOCOL.Start.Substitute] = 'Substitute';
|
|
153
|
+
START[1] = START[0].slice(0);
|
|
154
|
+
START[1][data_1.PROTOCOL.Start.Bide] = 'move: Bide';
|
|
155
|
+
const END = [new Array(data_1.PROTOCOL.End.length)];
|
|
156
|
+
END[0][data_1.PROTOCOL.End.Disable] = 'Disable';
|
|
157
|
+
END[0][data_1.PROTOCOL.End.Confusion] = 'confusion';
|
|
158
|
+
END[0][data_1.PROTOCOL.End.Bide] = 'Bide';
|
|
159
|
+
END[0][data_1.PROTOCOL.End.Substitute] = 'Substitute';
|
|
160
|
+
END[0][data_1.PROTOCOL.End.DisableSilent] = 'Disable';
|
|
161
|
+
END[0][data_1.PROTOCOL.End.ConfusionSilent] = 'confusion';
|
|
162
|
+
END[0][data_1.PROTOCOL.End.MistSilent] = 'Mist';
|
|
163
|
+
END[0][data_1.PROTOCOL.End.FocusEnergySilent] = 'move: Focus Energy';
|
|
164
|
+
END[0][data_1.PROTOCOL.End.LeechSeedSilent] = 'move: Leech Seed';
|
|
165
|
+
END[0][data_1.PROTOCOL.End.ToxicSilent] = 'Toxic counter';
|
|
166
|
+
END[0][data_1.PROTOCOL.End.LightScreenSilent] = 'Light Screen';
|
|
167
|
+
END[0][data_1.PROTOCOL.End.ReflectSilent] = 'Reflect';
|
|
168
|
+
END[0][data_1.PROTOCOL.End.BideSilent] = 'move: Bide';
|
|
169
|
+
END[1] = END[0].slice(0);
|
|
170
|
+
END[1][data_1.PROTOCOL.End.Disable] = 'move: Disable';
|
|
171
|
+
END[1][data_1.PROTOCOL.End.Bide] = 'move: Bide';
|
|
172
|
+
END[1][data_1.PROTOCOL.End.LeechSeed] = 'Leech Seed';
|
|
173
|
+
const SIDE = new Array(data_1.PROTOCOL.Side.length);
|
|
174
|
+
SIDE[data_1.PROTOCOL.Side.Safeguard] = 'Safeguard';
|
|
175
|
+
SIDE[data_1.PROTOCOL.Side.Reflect] = 'Reflect';
|
|
176
|
+
SIDE[data_1.PROTOCOL.Side.LightScreen] = 'move: Light Screen';
|
|
177
|
+
SIDE[data_1.PROTOCOL.Side.Spikes] = 'Spikes';
|
|
163
178
|
const DECODERS = new Array(ArgType.length);
|
|
164
179
|
DECODERS[ArgType.Move] = function (offset, data) {
|
|
165
180
|
const source = decodeIdent(this.info, data.getUint8(offset++));
|
|
@@ -179,7 +194,7 @@ DECODERS[ArgType.Move] = function (offset, data) {
|
|
|
179
194
|
DECODERS[ArgType.Switch] = function (offset, data) {
|
|
180
195
|
const ident = decodeIdent(this.info, data.getUint8(offset++));
|
|
181
196
|
const details = decodeDetails(offset, data, this.gen, this.lookup);
|
|
182
|
-
offset += 2;
|
|
197
|
+
offset += this.gen.num > 1 ? 3 : 2;
|
|
183
198
|
const hpStatus = decodeHPStatus(offset, data);
|
|
184
199
|
offset += 5;
|
|
185
200
|
const args = ['switch', ident, details, hpStatus];
|
|
@@ -334,9 +349,10 @@ DECODERS[ArgType.Activate] = function (offset, data) {
|
|
|
334
349
|
const ident = decodeIdent(this.info, data.getUint8(offset++));
|
|
335
350
|
const reason = data.getUint8(offset++);
|
|
336
351
|
const type = reason === data_1.PROTOCOL.Activate.Mist ? '-block' : '-activate';
|
|
352
|
+
const activate = ACTIVATE[this.gen.num - 1];
|
|
337
353
|
const args = reason === data_1.PROTOCOL.Activate.Splash
|
|
338
|
-
? [type, '',
|
|
339
|
-
: [type, ident,
|
|
354
|
+
? [type, '', activate[reason]]
|
|
355
|
+
: [type, ident, activate[reason], ''];
|
|
340
356
|
const kwArgs = reason === data_1.PROTOCOL.Activate.Substitute ? { damage: true } : {};
|
|
341
357
|
return { offset, line: { args, kwArgs } };
|
|
342
358
|
};
|
|
@@ -351,7 +367,7 @@ DECODERS[ArgType.Start] = function (offset, data) {
|
|
|
351
367
|
let args;
|
|
352
368
|
const kwArgs = {};
|
|
353
369
|
if (reason < data_1.PROTOCOL.Start.TypeChange) {
|
|
354
|
-
args = ['-start', ident, START[reason]];
|
|
370
|
+
args = ['-start', ident, START[this.gen.num - 1][reason]];
|
|
355
371
|
if (reason === data_1.PROTOCOL.Start.ConfusionSilent)
|
|
356
372
|
kwArgs.silent = true;
|
|
357
373
|
}
|
|
@@ -372,7 +388,7 @@ DECODERS[ArgType.Start] = function (offset, data) {
|
|
|
372
388
|
DECODERS[ArgType.End] = function (offset, data) {
|
|
373
389
|
const ident = decodeIdent(this.info, data.getUint8(offset++));
|
|
374
390
|
const reason = data.getUint8(offset++);
|
|
375
|
-
const args = ['-end', ident, END[reason]];
|
|
391
|
+
const args = ['-end', ident, END[this.gen.num - 1][reason]];
|
|
376
392
|
const kwArgs = reason >= data_1.PROTOCOL.End.DisableSilent ? { silent: true } : {};
|
|
377
393
|
return { offset, line: { args, kwArgs } };
|
|
378
394
|
};
|
|
@@ -411,8 +427,11 @@ function decodeIdent(info, byte) {
|
|
|
411
427
|
}
|
|
412
428
|
function decodeDetails(offset, data, gen, lookup) {
|
|
413
429
|
const species = gen.species.get(lookup.speciesByNum(data.getUint8(offset++))).name;
|
|
430
|
+
const gender = gen.num > 1 ? GENDERS[data.getUint8(offset++)] : 'N';
|
|
414
431
|
const level = data.getUint8(offset);
|
|
415
|
-
|
|
432
|
+
const mf = gender === 'N' ? '' : `, ${gender}`;
|
|
433
|
+
const lvl = level === 100 ? '' : `, L${level}`;
|
|
434
|
+
return `${species}${mf}${lvl}`;
|
|
416
435
|
}
|
|
417
436
|
function decodeHPStatus(offset, data) {
|
|
418
437
|
const hp = data.getUint16(offset, data_1.LE);
|