@pkmn/engine 0.1.0-dev.fb5bf955 → 0.1.0-dev.fb6653d6
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/LICENSE +1 -3
- package/README.md +115 -76
- package/build/pkg/addon/browser.d.ts +3 -0
- package/build/pkg/addon/browser.js +44 -0
- package/build/pkg/addon/browser.js.map +1 -0
- package/build/pkg/addon/node.d.ts +3 -0
- package/build/pkg/addon/node.js +97 -0
- package/build/pkg/addon/node.js.map +1 -0
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +53 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +27 -5
- package/build/pkg/addon.js +42 -73
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +40 -5
- package/build/pkg/data/protocol.json +84 -13
- package/build/pkg/data.d.ts +27 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +16 -19
- package/build/pkg/gen1.js +54 -42
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +55 -103
- package/build/pkg/index.js +6 -63
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +24 -3
- package/build/pkg/protocol.js +127 -104
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +36 -69
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +141 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +142 -0
- package/build/tools/display/index.js.map +1 -0
- package/build/tools/display/ui.jsx +349 -0
- package/build/tools/display/ui.jsx.map +1 -0
- package/build/tools/display/util.js +18 -0
- package/build/tools/display/util.js.map +1 -0
- package/build.zig +373 -152
- package/package.json +68 -120
- package/src/bin/install-pkmn-engine +41 -26
- package/src/bin/pkmn-debug +29 -6
- package/src/lib/bindings/node.zig +121 -0
- package/src/lib/bindings/wasm.zig +58 -0
- package/src/lib/common/array.zig +77 -0
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +19 -31
- package/src/lib/common/debug.zig +58 -17
- package/src/lib/common/js.zig +120 -0
- package/src/lib/common/optional.zig +71 -0
- package/src/lib/common/options.zig +18 -3
- package/src/lib/common/protocol.zig +947 -407
- package/src/lib/common/rational.zig +449 -0
- package/src/lib/common/rng.zig +31 -24
- package/src/lib/common/util.zig +61 -0
- package/src/lib/gen1/calc.zig +953 -0
- package/src/lib/gen1/chance.zig +1185 -0
- package/src/lib/gen1/data/moves.zig +203 -193
- package/src/lib/gen1/data/species.zig +6 -8
- package/src/lib/gen1/data/types.zig +11 -12
- package/src/lib/gen1/data.zig +100 -89
- package/src/lib/gen1/helpers.zig +139 -50
- package/src/lib/gen1/mechanics.zig +1344 -907
- package/src/lib/gen2/calc.zig +153 -0
- package/src/lib/gen2/chance.zig +902 -0
- package/src/lib/gen2/data/items.zig +15 -23
- package/src/lib/gen2/data/moves.zig +665 -573
- package/src/lib/gen2/data/species.zig +3 -5
- package/src/lib/gen2/data/types.zig +138 -36
- package/src/lib/gen2/data.zig +134 -99
- package/src/lib/gen2/generated.zig +801 -0
- package/src/lib/gen2/helpers.zig +59 -44
- package/src/lib/gen2/mechanics.zig +3582 -30
- package/src/lib/node.zig +18 -0
- package/src/lib/pkmn.zig +93 -12
- package/src/lib/wasm.zig +17 -0
- package/src/tools/display/dom.ts +96 -0
- package/src/tools/display/ui.css +354 -0
- package/build/test/display.js +0 -382
- package/build/test/display.js.map +0 -1
- package/src/lib/binding/node.zig +0 -229
- package/src/lib/binding/wasm.zig +0 -10
- package/src/lib/gen1/README.md +0 -784
- package/src/lib/gen2/README.md +0 -309
- package/src/test/display/pkmn.html.tmpl +0 -368
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
1
|
const builtin = @import("builtin");
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
2
|
+
const data = @import("data.zig");
|
|
3
|
+
const options = @import("options.zig");
|
|
4
|
+
const pkmn = @import("../pkmn.zig");
|
|
5
|
+
const std = @import("std");
|
|
6
6
|
|
|
7
7
|
const assert = std.debug.assert;
|
|
8
|
+
const enabled = options.log;
|
|
9
|
+
const ID = data.ID;
|
|
10
|
+
const Player = data.Player;
|
|
8
11
|
const print = std.debug.print;
|
|
9
12
|
|
|
10
|
-
const
|
|
13
|
+
const endian = builtin.cpu.arch.endian();
|
|
14
|
+
const Endian = std.builtin.Endian;
|
|
15
|
+
const big = if (@hasField(Endian, "big")) Endian.big else Endian.Big;
|
|
16
|
+
const little = if (@hasField(Endian, "little")) Endian.little else Endian.Little;
|
|
11
17
|
|
|
12
|
-
const
|
|
13
|
-
const ID = data.ID;
|
|
18
|
+
const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
|
|
14
19
|
|
|
15
20
|
pub const ArgType = enum(u8) {
|
|
16
21
|
None,
|
|
@@ -69,7 +74,7 @@ pub const ArgType = enum(u8) {
|
|
|
69
74
|
EndAbility,
|
|
70
75
|
ClearNegativeBoost,
|
|
71
76
|
FormeChange,
|
|
72
|
-
|
|
77
|
+
LastNoTarget, // FIXME
|
|
73
78
|
|
|
74
79
|
// Gen 4
|
|
75
80
|
SwapBoost,
|
|
@@ -102,6 +107,10 @@ pub const ArgType = enum(u8) {
|
|
|
102
107
|
// Gen 8
|
|
103
108
|
CanDynamax,
|
|
104
109
|
SwapSideConditions,
|
|
110
|
+
UpdatePoke,
|
|
111
|
+
|
|
112
|
+
// Gen 9
|
|
113
|
+
Terastallize,
|
|
105
114
|
};
|
|
106
115
|
|
|
107
116
|
pub const Move = enum(u8) {
|
|
@@ -118,12 +127,19 @@ pub const Cant = enum(u8) {
|
|
|
118
127
|
Disable,
|
|
119
128
|
Recharge,
|
|
120
129
|
PP,
|
|
130
|
+
|
|
131
|
+
Attract,
|
|
121
132
|
};
|
|
122
133
|
|
|
123
134
|
pub const Heal = enum(u8) {
|
|
124
135
|
None,
|
|
125
136
|
Silent,
|
|
126
137
|
Drain,
|
|
138
|
+
|
|
139
|
+
Leftovers,
|
|
140
|
+
Berry,
|
|
141
|
+
BerryJuice,
|
|
142
|
+
GoldBerry,
|
|
127
143
|
};
|
|
128
144
|
|
|
129
145
|
pub const Damage = enum(u8) {
|
|
@@ -133,6 +149,17 @@ pub const Damage = enum(u8) {
|
|
|
133
149
|
Confusion,
|
|
134
150
|
LeechSeed,
|
|
135
151
|
RecoilOf,
|
|
152
|
+
|
|
153
|
+
Bind,
|
|
154
|
+
Wrap,
|
|
155
|
+
FireSpin,
|
|
156
|
+
Clamp,
|
|
157
|
+
Whirlpool,
|
|
158
|
+
Spikes,
|
|
159
|
+
|
|
160
|
+
Nightmare,
|
|
161
|
+
Curse,
|
|
162
|
+
Sandstorm,
|
|
136
163
|
};
|
|
137
164
|
|
|
138
165
|
pub const Status = enum(u8) {
|
|
@@ -175,8 +202,26 @@ pub const Activate = enum(u8) {
|
|
|
175
202
|
Haze,
|
|
176
203
|
Mist,
|
|
177
204
|
Struggle,
|
|
178
|
-
Substitute,
|
|
205
|
+
Substitute, // FIXME SubstituteDamage
|
|
179
206
|
Splash,
|
|
207
|
+
|
|
208
|
+
Rage, // TODO
|
|
209
|
+
|
|
210
|
+
Attract,
|
|
211
|
+
LockOn,
|
|
212
|
+
Bind,
|
|
213
|
+
Wrap,
|
|
214
|
+
FireSpin,
|
|
215
|
+
Clamp,
|
|
216
|
+
Whirlpool,
|
|
217
|
+
SubstituteBlock,
|
|
218
|
+
|
|
219
|
+
DestinyBond,
|
|
220
|
+
|
|
221
|
+
BeatUp, // FIXME of
|
|
222
|
+
|
|
223
|
+
Magnitude,
|
|
224
|
+
Spite,
|
|
180
225
|
};
|
|
181
226
|
|
|
182
227
|
pub const Start = enum(u8) {
|
|
@@ -194,6 +239,19 @@ pub const Start = enum(u8) {
|
|
|
194
239
|
|
|
195
240
|
Disable,
|
|
196
241
|
Mimic,
|
|
242
|
+
|
|
243
|
+
Attract,
|
|
244
|
+
Nightmare,
|
|
245
|
+
Curse,
|
|
246
|
+
Foresight,
|
|
247
|
+
Encore,
|
|
248
|
+
FutureSight,
|
|
249
|
+
|
|
250
|
+
PerishSong0,
|
|
251
|
+
PerishSong1,
|
|
252
|
+
PerishSong2,
|
|
253
|
+
PerishSong3,
|
|
254
|
+
PerishSong3Silent,
|
|
197
255
|
};
|
|
198
256
|
|
|
199
257
|
pub const End = enum(u8) {
|
|
@@ -202,16 +260,30 @@ pub const End = enum(u8) {
|
|
|
202
260
|
Bide,
|
|
203
261
|
Substitute,
|
|
204
262
|
|
|
205
|
-
|
|
263
|
+
Nightmare,
|
|
264
|
+
Curse,
|
|
265
|
+
Foresight,
|
|
266
|
+
Encore,
|
|
267
|
+
FutureSight,
|
|
268
|
+
LeechSeed,
|
|
269
|
+
|
|
270
|
+
Bind,
|
|
271
|
+
Wrap,
|
|
272
|
+
FireSpin,
|
|
273
|
+
Clamp,
|
|
274
|
+
Whirlpool,
|
|
275
|
+
|
|
206
276
|
DisableSilent,
|
|
207
277
|
ConfusionSilent,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
278
|
+
MistSilent,
|
|
279
|
+
FocusEnergySilent,
|
|
280
|
+
LeechSeedSilent,
|
|
281
|
+
ToxicSilent,
|
|
282
|
+
LightScreenSilent,
|
|
283
|
+
ReflectSilent,
|
|
284
|
+
BideSilent,
|
|
285
|
+
|
|
286
|
+
LeechSeedFrom,
|
|
215
287
|
};
|
|
216
288
|
|
|
217
289
|
pub const Immune = enum(u8) {
|
|
@@ -219,8 +291,34 @@ pub const Immune = enum(u8) {
|
|
|
219
291
|
OHKO,
|
|
220
292
|
};
|
|
221
293
|
|
|
294
|
+
pub const EndItem = enum(u8) {
|
|
295
|
+
None,
|
|
296
|
+
Eat,
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
pub const SetHP = enum(u8) {
|
|
300
|
+
None,
|
|
301
|
+
Silent,
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
pub const Side = enum(u8) {
|
|
305
|
+
Safeguard,
|
|
306
|
+
Reflect,
|
|
307
|
+
LightScreen,
|
|
308
|
+
Spikes,
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
pub const Weather = enum(u8) {
|
|
312
|
+
None,
|
|
313
|
+
Upkeep,
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
/// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
|
|
317
|
+
/// Ignores anything sent to it, though protocol logging should additionally be turned off
|
|
318
|
+
/// entirely with `options.log`.
|
|
222
319
|
pub const NULL = Log(@TypeOf(std.io.null_writer)){ .writer = std.io.null_writer };
|
|
223
320
|
|
|
321
|
+
/// Logs protocol information to its `Writer` during a battle update when `options.log` is enabled.
|
|
224
322
|
pub fn Log(comptime Writer: type) type {
|
|
225
323
|
return struct {
|
|
226
324
|
const Self = @This();
|
|
@@ -229,322 +327,501 @@ pub fn Log(comptime Writer: type) type {
|
|
|
229
327
|
|
|
230
328
|
pub const Error = Writer.Error;
|
|
231
329
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
330
|
+
// source: ID, move: <Move>, target: ID, from?: <Move>
|
|
331
|
+
pub fn move(self: Self, args: anytype) Error!void {
|
|
332
|
+
if (!enabled) return;
|
|
333
|
+
|
|
334
|
+
assert(args[1] != .None);
|
|
235
335
|
try self.writer.writeAll(&.{
|
|
236
|
-
@
|
|
237
|
-
@
|
|
238
|
-
@
|
|
239
|
-
@
|
|
336
|
+
@intFromEnum(ArgType.Move),
|
|
337
|
+
@as(u8, @bitCast(args[0])),
|
|
338
|
+
@intFromEnum(args[1]),
|
|
339
|
+
@as(u8, @bitCast(args[2])),
|
|
240
340
|
});
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
341
|
+
try self.writer.writeAll(if (args.len < 4 or @intFromEnum(args[3]) == 0)
|
|
342
|
+
&.{@intFromEnum(Move.None)}
|
|
343
|
+
else
|
|
344
|
+
&.{ @intFromEnum(Move.From), @intFromEnum(args[3]) });
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ident: ID, pokemon: <Pokemon>
|
|
348
|
+
pub fn switched(self: Self, args: anytype) Error!void {
|
|
349
|
+
return switchDrag(self, .Switch, args);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ident: ID, pokemon: <Pokemon>
|
|
353
|
+
fn switchDrag(self: Self, arg: ArgType, args: anytype) Error!void {
|
|
354
|
+
if (!enabled) return;
|
|
355
|
+
|
|
356
|
+
try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(args[0])) });
|
|
357
|
+
if (@hasField(@TypeOf(args[1].*), "dvs")) {
|
|
358
|
+
try self.writer.writeAll(&.{
|
|
359
|
+
@intFromEnum(args[1].species),
|
|
360
|
+
@intFromEnum(args[1].dvs.gender),
|
|
361
|
+
args[1].level,
|
|
362
|
+
});
|
|
363
|
+
} else {
|
|
364
|
+
try self.writer.writeAll(&.{ @intFromEnum(args[1].species), args[1].level });
|
|
365
|
+
}
|
|
366
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
367
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
368
|
+
try self.writer.writeAll(&.{args[1].status});
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// ident: ID, reason: Cant
|
|
372
|
+
// ident: ID, reason: .Disable, move: <Move>
|
|
373
|
+
pub fn cant(self: Self, args: anytype) Error!void {
|
|
374
|
+
if (!enabled) return;
|
|
375
|
+
|
|
376
|
+
assert(args[1] != .Disable or args.len == 3);
|
|
377
|
+
try self.writer.writeAll(&.{
|
|
378
|
+
@intFromEnum(ArgType.Cant),
|
|
379
|
+
@as(u8, @bitCast(args[0])),
|
|
380
|
+
@intFromEnum(@as(Cant, args[1])),
|
|
252
381
|
});
|
|
382
|
+
if (args.len == 3) try self.writer.writeByte(@intFromEnum(args[2]));
|
|
253
383
|
}
|
|
254
384
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
try self.writer.
|
|
260
|
-
try self.writer.
|
|
261
|
-
|
|
385
|
+
// ident: ID, done: bool
|
|
386
|
+
pub fn faint(self: Self, args: anytype) Error!void {
|
|
387
|
+
if (!enabled) return;
|
|
388
|
+
|
|
389
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(args[0])) });
|
|
390
|
+
if (args[1]) try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// num: u16
|
|
394
|
+
pub fn turn(self: Self, args: anytype) Error!void {
|
|
395
|
+
if (!enabled) return;
|
|
396
|
+
|
|
397
|
+
try self.writer.writeByte(@intFromEnum(ArgType.Turn));
|
|
398
|
+
try self.writer.writeInt(u16, args[0], endian);
|
|
399
|
+
try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
262
400
|
}
|
|
263
401
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
402
|
+
// player: Player
|
|
403
|
+
pub fn win(self: Self, args: anytype) Error!void {
|
|
404
|
+
if (!enabled) return;
|
|
405
|
+
|
|
267
406
|
try self.writer.writeAll(&.{
|
|
268
|
-
@
|
|
269
|
-
@
|
|
270
|
-
@
|
|
407
|
+
@intFromEnum(ArgType.Win),
|
|
408
|
+
@intFromEnum(@as(Player, args[0])),
|
|
409
|
+
@intFromEnum(ArgType.None),
|
|
271
410
|
});
|
|
272
411
|
}
|
|
273
412
|
|
|
274
|
-
|
|
275
|
-
|
|
413
|
+
// -
|
|
414
|
+
pub fn tie(self: Self, _: anytype) Error!void {
|
|
415
|
+
if (!enabled) return;
|
|
416
|
+
|
|
417
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ident: ID, pokemon: <Pokemon>, reason: Damage
|
|
421
|
+
// ident: ID, pokemon: <Pokemon>, reason: .RecoilOf, source: ID
|
|
422
|
+
pub fn damage(self: Self, args: anytype) Error!void {
|
|
423
|
+
if (!enabled) return;
|
|
424
|
+
|
|
425
|
+
assert(args[2] != .RecoilOf or args.len == 4);
|
|
276
426
|
try self.writer.writeAll(&.{
|
|
277
|
-
@
|
|
278
|
-
@
|
|
279
|
-
@enumToInt(Cant.Disable),
|
|
280
|
-
@enumToInt(m),
|
|
427
|
+
@intFromEnum(ArgType.Damage),
|
|
428
|
+
@as(u8, @bitCast(args[0])),
|
|
281
429
|
});
|
|
430
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
431
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
432
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Damage, args[2])) });
|
|
433
|
+
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
282
434
|
}
|
|
283
435
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
if (
|
|
436
|
+
// ident: ID, pokemon: <Pokemon>, reason: Heal
|
|
437
|
+
// ident: ID, pokemon: <Pokemon>, reason: .Drain, target: ID
|
|
438
|
+
pub fn heal(self: Self, args: anytype) Error!void {
|
|
439
|
+
if (!enabled) return;
|
|
440
|
+
|
|
441
|
+
assert(args[2] != .Drain or args.len == 4);
|
|
442
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
|
|
443
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
444
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
445
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Heal, args[2])) });
|
|
446
|
+
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
288
447
|
}
|
|
289
448
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
449
|
+
// ident: ID, value: u8, reason: Status
|
|
450
|
+
// ident: ID, value: u8, reason: .From, m: <Move>
|
|
451
|
+
pub fn status(self: Self, args: anytype) Error!void {
|
|
452
|
+
if (!enabled) return;
|
|
453
|
+
|
|
454
|
+
assert(args[2] != .From or args.len == 4);
|
|
455
|
+
try self.writer.writeAll(&.{
|
|
456
|
+
@intFromEnum(ArgType.Status),
|
|
457
|
+
@as(u8, @bitCast(args[0])),
|
|
458
|
+
args[1],
|
|
459
|
+
@intFromEnum(@as(Status, args[2])),
|
|
460
|
+
});
|
|
461
|
+
if (args.len == 4) try self.writer.writeByte(@intFromEnum(args[3]));
|
|
295
462
|
}
|
|
296
463
|
|
|
297
|
-
|
|
298
|
-
|
|
464
|
+
// ident: ID, value: u8, reason: CureStatus
|
|
465
|
+
pub fn curestatus(self: Self, args: anytype) Error!void {
|
|
466
|
+
if (!enabled) return;
|
|
467
|
+
|
|
299
468
|
try self.writer.writeAll(&.{
|
|
300
|
-
@
|
|
301
|
-
@
|
|
302
|
-
|
|
469
|
+
@intFromEnum(ArgType.CureStatus),
|
|
470
|
+
@as(u8, @bitCast(args[0])),
|
|
471
|
+
args[1],
|
|
472
|
+
@intFromEnum(@as(CureStatus, args[2])),
|
|
303
473
|
});
|
|
304
474
|
}
|
|
305
475
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
476
|
+
// ident: ID, reason: Boost, num: i8
|
|
477
|
+
pub fn boost(self: Self, args: anytype) Error!void {
|
|
478
|
+
if (!enabled) return;
|
|
479
|
+
|
|
480
|
+
assert(args[2] != 0 and (args[1] != .Rage or args[2] > 0));
|
|
481
|
+
try self.writer.writeAll(&.{
|
|
482
|
+
@intFromEnum(ArgType.Boost),
|
|
483
|
+
@as(u8, @bitCast(args[0])),
|
|
484
|
+
@intFromEnum(@as(Boost, args[1])),
|
|
485
|
+
@as(u8, @intCast(@as(i8, args[2]) + 6)),
|
|
486
|
+
});
|
|
309
487
|
}
|
|
310
488
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
try self.writer.
|
|
316
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
317
|
-
try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
|
|
489
|
+
// -
|
|
490
|
+
pub fn clearallboost(self: Self, _: anytype) Error!void {
|
|
491
|
+
if (!enabled) return;
|
|
492
|
+
|
|
493
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
|
|
318
494
|
}
|
|
319
495
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
reason: Damage,
|
|
325
|
-
source: ID,
|
|
326
|
-
) Error!void {
|
|
327
|
-
if (!trace) return;
|
|
328
|
-
assert(@enumToInt(reason) == @enumToInt(Damage.RecoilOf));
|
|
329
|
-
try self.writer.writeAll(&.{ @enumToInt(ArgType.Damage), @bitCast(u8, ident) });
|
|
330
|
-
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
331
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
496
|
+
// ident: ID, reason: Fail
|
|
497
|
+
pub fn fail(self: Self, args: anytype) Error!void {
|
|
498
|
+
if (!enabled) return;
|
|
499
|
+
|
|
332
500
|
try self.writer.writeAll(&.{
|
|
333
|
-
|
|
334
|
-
@
|
|
335
|
-
@
|
|
501
|
+
@intFromEnum(ArgType.Fail),
|
|
502
|
+
@as(u8, @bitCast(args[0])),
|
|
503
|
+
@intFromEnum(@as(Fail, args[1])),
|
|
336
504
|
});
|
|
337
505
|
}
|
|
338
506
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
try self.writer.
|
|
344
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
345
|
-
try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
|
|
507
|
+
// source: ID
|
|
508
|
+
pub fn miss(self: Self, args: anytype) Error!void {
|
|
509
|
+
if (!enabled) return;
|
|
510
|
+
|
|
511
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(args[0])) });
|
|
346
512
|
}
|
|
347
513
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
514
|
+
// ident: ID, num: u8
|
|
515
|
+
pub fn hitcount(self: Self, args: anytype) Error!void {
|
|
516
|
+
if (!enabled) return;
|
|
517
|
+
|
|
353
518
|
try self.writer.writeAll(&.{
|
|
354
|
-
|
|
355
|
-
@
|
|
356
|
-
|
|
519
|
+
@intFromEnum(ArgType.HitCount),
|
|
520
|
+
@as(u8, @bitCast(args[0])),
|
|
521
|
+
args[1],
|
|
357
522
|
});
|
|
358
523
|
}
|
|
359
524
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
525
|
+
// source: ID, m: <Move>
|
|
526
|
+
pub fn prepare(self: Self, args: anytype) Error!void {
|
|
527
|
+
if (!enabled) return;
|
|
528
|
+
|
|
363
529
|
try self.writer.writeAll(&.{
|
|
364
|
-
@
|
|
365
|
-
@
|
|
366
|
-
|
|
367
|
-
@enumToInt(reason),
|
|
530
|
+
@intFromEnum(ArgType.Prepare),
|
|
531
|
+
@as(u8, @bitCast(args[0])),
|
|
532
|
+
@intFromEnum(args[1]),
|
|
368
533
|
});
|
|
369
534
|
}
|
|
370
535
|
|
|
371
|
-
|
|
372
|
-
|
|
536
|
+
// ident: ID
|
|
537
|
+
pub fn mustrecharge(self: Self, args: anytype) Error!void {
|
|
538
|
+
if (!enabled) return;
|
|
539
|
+
|
|
373
540
|
try self.writer.writeAll(&.{
|
|
374
|
-
@
|
|
375
|
-
@
|
|
376
|
-
value,
|
|
377
|
-
@enumToInt(Status.From),
|
|
378
|
-
@enumToInt(m),
|
|
541
|
+
@intFromEnum(ArgType.MustRecharge),
|
|
542
|
+
@as(u8, @bitCast(args[0])),
|
|
379
543
|
});
|
|
380
544
|
}
|
|
381
545
|
|
|
382
|
-
|
|
383
|
-
|
|
546
|
+
// ident: ID, reason: Activate
|
|
547
|
+
// ident: ID, reason: .SubstituteBlock, m: <Move>
|
|
548
|
+
// ident: ID, reason: .Magnitude, num: u8
|
|
549
|
+
// ident: ID, reason: .Spite, m: <Move>, num: u8
|
|
550
|
+
pub fn activate(self: Self, args: anytype) Error!void {
|
|
551
|
+
if (!enabled) return;
|
|
552
|
+
|
|
553
|
+
assert(args.len <= 4);
|
|
554
|
+
const reason: Activate = args[1];
|
|
384
555
|
try self.writer.writeAll(&.{
|
|
385
|
-
@
|
|
386
|
-
@
|
|
387
|
-
|
|
388
|
-
@enumToInt(reason),
|
|
556
|
+
@intFromEnum(ArgType.Activate),
|
|
557
|
+
@as(u8, @bitCast(args[0])),
|
|
558
|
+
@intFromEnum(reason),
|
|
389
559
|
});
|
|
560
|
+
if (args.len == 3) {
|
|
561
|
+
if (reason == .SubstituteBlock) {
|
|
562
|
+
try self.writer.writeByte(@intFromEnum(args[2]));
|
|
563
|
+
} else {
|
|
564
|
+
assert(reason == .Magnitude);
|
|
565
|
+
try self.writer.writeByte(args[2]);
|
|
566
|
+
}
|
|
567
|
+
} else if (args.len == 4) {
|
|
568
|
+
assert(reason == .Spite);
|
|
569
|
+
try self.writer.writeAll(&.{ @intFromEnum(args[2]), args[3] });
|
|
570
|
+
}
|
|
390
571
|
}
|
|
391
572
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
573
|
+
// -
|
|
574
|
+
pub fn fieldactivate(self: Self, _: anytype) Error!void {
|
|
575
|
+
if (!enabled) return;
|
|
576
|
+
|
|
577
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// ident: ID, reason: Start
|
|
581
|
+
// ident: ID, reason: .Disable | .Mimic | .Encore, m: <Move>
|
|
582
|
+
// ident: ID, reason: .TypeChange, types: <Types>, target: ID
|
|
583
|
+
pub fn start(self: Self, args: anytype) Error!void {
|
|
584
|
+
if (!enabled) return;
|
|
585
|
+
|
|
586
|
+
assert(args.len <= 4);
|
|
587
|
+
const reason: Start = args[1];
|
|
395
588
|
try self.writer.writeAll(&.{
|
|
396
|
-
@
|
|
397
|
-
@
|
|
398
|
-
@
|
|
399
|
-
@intCast(u8, num + 6),
|
|
589
|
+
@intFromEnum(ArgType.Start),
|
|
590
|
+
@as(u8, @bitCast(args[0])),
|
|
591
|
+
@intFromEnum(reason),
|
|
400
592
|
});
|
|
593
|
+
if (args.len == 3) {
|
|
594
|
+
assert(reason == .Disable or reason == .Mimic or reason == .Encore);
|
|
595
|
+
try self.writer.writeByte(@intFromEnum(args[2]));
|
|
596
|
+
} else if (args.len == 4) {
|
|
597
|
+
assert(reason == .TypeChange);
|
|
598
|
+
// FIXME: u16 types in Generation II
|
|
599
|
+
try self.writer.writeAll(&.{
|
|
600
|
+
@as(u8, @bitCast(args[2])),
|
|
601
|
+
@as(u8, @bitCast(args[3])),
|
|
602
|
+
});
|
|
603
|
+
}
|
|
401
604
|
}
|
|
402
605
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
606
|
+
// ident: ID, reason: End
|
|
607
|
+
pub fn end(self: Self, args: anytype) Error!void {
|
|
608
|
+
if (!enabled) return;
|
|
407
609
|
|
|
408
|
-
pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
|
|
409
|
-
if (!trace) return;
|
|
410
610
|
try self.writer.writeAll(&.{
|
|
411
|
-
@
|
|
412
|
-
@
|
|
413
|
-
@
|
|
611
|
+
@intFromEnum(ArgType.End),
|
|
612
|
+
@as(u8, @bitCast(args[0])),
|
|
613
|
+
@intFromEnum(@as(End, args[1])),
|
|
414
614
|
});
|
|
415
615
|
}
|
|
416
616
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
617
|
+
// -
|
|
618
|
+
pub fn ohko(self: Self, _: anytype) Error!void {
|
|
619
|
+
if (!enabled) return;
|
|
620
|
+
|
|
621
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// ident: ID
|
|
625
|
+
pub fn crit(self: Self, args: anytype) Error!void {
|
|
626
|
+
if (!enabled) return;
|
|
627
|
+
|
|
628
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(args[0])) });
|
|
420
629
|
}
|
|
421
630
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
631
|
+
// ident: ID
|
|
632
|
+
pub fn supereffective(self: Self, args: anytype) Error!void {
|
|
633
|
+
if (!enabled) return;
|
|
634
|
+
|
|
635
|
+
try self.writer.writeAll(&.{
|
|
636
|
+
@intFromEnum(ArgType.SuperEffective),
|
|
637
|
+
@as(u8, @bitCast(args[0])),
|
|
638
|
+
});
|
|
425
639
|
}
|
|
426
640
|
|
|
427
|
-
|
|
428
|
-
|
|
641
|
+
// ident: ID
|
|
642
|
+
pub fn resisted(self: Self, args: anytype) Error!void {
|
|
643
|
+
if (!enabled) return;
|
|
644
|
+
|
|
429
645
|
try self.writer.writeAll(&.{
|
|
430
|
-
@
|
|
431
|
-
@
|
|
432
|
-
@enumToInt(m),
|
|
646
|
+
@intFromEnum(ArgType.Resisted),
|
|
647
|
+
@as(u8, @bitCast(args[0])),
|
|
433
648
|
});
|
|
434
649
|
}
|
|
435
650
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
651
|
+
// ident: ID, reason: Immune
|
|
652
|
+
pub fn immune(self: Self, args: anytype) Error!void {
|
|
653
|
+
if (!enabled) return;
|
|
654
|
+
|
|
655
|
+
try self.writer.writeAll(&.{
|
|
656
|
+
@intFromEnum(ArgType.Immune),
|
|
657
|
+
@as(u8, @bitCast(args[0])),
|
|
658
|
+
@intFromEnum(@as(Immune, args[1])),
|
|
659
|
+
});
|
|
439
660
|
}
|
|
440
661
|
|
|
441
|
-
|
|
442
|
-
|
|
662
|
+
// source: ID, target: ID
|
|
663
|
+
pub fn transform(self: Self, args: anytype) Error!void {
|
|
664
|
+
if (!enabled) return;
|
|
665
|
+
|
|
443
666
|
try self.writer.writeAll(&.{
|
|
444
|
-
@
|
|
445
|
-
@
|
|
446
|
-
@
|
|
667
|
+
@intFromEnum(ArgType.Transform),
|
|
668
|
+
@as(u8, @bitCast(args[0])),
|
|
669
|
+
@as(u8, @bitCast(args[1])),
|
|
447
670
|
});
|
|
448
671
|
}
|
|
449
672
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
673
|
+
// ident: ID, pokemon: <Pokemon>
|
|
674
|
+
pub fn drag(self: Self, args: anytype) Error!void {
|
|
675
|
+
return switchDrag(self, .Drag, args);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// target: ID, item: <Item>, source: ID
|
|
679
|
+
pub fn item(self: Self, args: anytype) Error!void {
|
|
680
|
+
if (!enabled) return;
|
|
681
|
+
|
|
682
|
+
try self.writer.writeAll(&.{
|
|
683
|
+
@intFromEnum(ArgType.Item),
|
|
684
|
+
@as(u8, @bitCast(args[0])),
|
|
685
|
+
@intFromEnum(args[1]),
|
|
686
|
+
@as(u8, @bitCast(args[2])),
|
|
687
|
+
});
|
|
453
688
|
}
|
|
454
689
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
690
|
+
// ident: ID, item: <Item>, reason: EndItem
|
|
691
|
+
pub fn enditem(self: Self, args: anytype) Error!void {
|
|
692
|
+
if (!enabled) return;
|
|
693
|
+
|
|
458
694
|
try self.writer.writeAll(&.{
|
|
459
|
-
@
|
|
460
|
-
@
|
|
461
|
-
@
|
|
695
|
+
@intFromEnum(ArgType.EndItem),
|
|
696
|
+
@as(u8, @bitCast(args[0])),
|
|
697
|
+
@intFromEnum(args[1]),
|
|
698
|
+
@intFromEnum(@as(EndItem, args[2])),
|
|
462
699
|
});
|
|
463
700
|
}
|
|
464
701
|
|
|
465
|
-
|
|
466
|
-
|
|
702
|
+
// source: ID
|
|
703
|
+
pub fn cureteam(self: Self, args: anytype) Error!void {
|
|
704
|
+
if (!enabled) return;
|
|
705
|
+
|
|
467
706
|
try self.writer.writeAll(&.{
|
|
468
|
-
@
|
|
469
|
-
@
|
|
470
|
-
@enumToInt(Start.TypeChange),
|
|
471
|
-
@bitCast(u8, types),
|
|
472
|
-
@bitCast(u8, target),
|
|
707
|
+
@intFromEnum(ArgType.CureTeam),
|
|
708
|
+
@as(u8, @bitCast(args[0])),
|
|
473
709
|
});
|
|
474
710
|
}
|
|
475
711
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
712
|
+
// ident: ID, pokemon: <Pokemon>, reason: SetHP
|
|
713
|
+
pub fn sethp(self: Self, args: anytype) Error!void {
|
|
714
|
+
if (!enabled) return;
|
|
715
|
+
|
|
716
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(args[0])) });
|
|
717
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
718
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
719
|
+
try self.writer.writeAll(&.{args[1].status});
|
|
720
|
+
try self.writer.writeByte(@intFromEnum(@as(SetHP, args[2])));
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// ident: ID, num: i8
|
|
724
|
+
pub fn setboost(self: Self, args: anytype) Error!void {
|
|
725
|
+
if (!enabled) return;
|
|
726
|
+
|
|
479
727
|
try self.writer.writeAll(&.{
|
|
480
|
-
@
|
|
481
|
-
@
|
|
482
|
-
@
|
|
483
|
-
@enumToInt(m),
|
|
728
|
+
@intFromEnum(ArgType.SetBoost),
|
|
729
|
+
@as(u8, @bitCast(args[0])),
|
|
730
|
+
@as(u8, @intCast(args[1] + 6)),
|
|
484
731
|
});
|
|
485
732
|
}
|
|
486
733
|
|
|
487
|
-
|
|
488
|
-
|
|
734
|
+
// source: ID, target: ID
|
|
735
|
+
pub fn copyboost(self: Self, args: anytype) Error!void {
|
|
736
|
+
if (!enabled) return;
|
|
737
|
+
|
|
489
738
|
try self.writer.writeAll(&.{
|
|
490
|
-
@
|
|
491
|
-
@
|
|
492
|
-
@
|
|
739
|
+
@intFromEnum(ArgType.CopyBoost),
|
|
740
|
+
@as(u8, @bitCast(args[0])),
|
|
741
|
+
@as(u8, @bitCast(args[1])),
|
|
493
742
|
});
|
|
494
743
|
}
|
|
495
744
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
745
|
+
// player: Player, reason: Side
|
|
746
|
+
pub fn sidestart(self: Self, args: anytype) Error!void {
|
|
747
|
+
if (!enabled) return;
|
|
748
|
+
|
|
749
|
+
try self.writer.writeAll(&.{
|
|
750
|
+
@intFromEnum(ArgType.SideStart),
|
|
751
|
+
@intFromEnum(@as(Player, args[0])),
|
|
752
|
+
@intFromEnum(@as(Side, args[1])),
|
|
753
|
+
});
|
|
499
754
|
}
|
|
500
755
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
756
|
+
// player: Player, reason: Side
|
|
757
|
+
// player: Player, reason: .Spikes, source: ID
|
|
758
|
+
pub fn sideend(self: Self, args: anytype) Error!void {
|
|
759
|
+
if (!enabled) return;
|
|
760
|
+
|
|
761
|
+
assert(args[1] != .Spikes or args.len == 3);
|
|
762
|
+
try self.writer.writeAll(&.{
|
|
763
|
+
@intFromEnum(ArgType.SideEnd),
|
|
764
|
+
@intFromEnum(@as(Player, args[0])),
|
|
765
|
+
@intFromEnum(@as(Side, args[1])),
|
|
766
|
+
});
|
|
767
|
+
if (args.len == 3) try self.writer.writeByte(@as(u8, @bitCast(args[2])));
|
|
504
768
|
}
|
|
505
769
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
770
|
+
// ident: ID, move: <Move>
|
|
771
|
+
pub fn singlemove(self: Self, args: anytype) Error!void {
|
|
772
|
+
return single(self, .SingleMove, args);
|
|
509
773
|
}
|
|
510
774
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
775
|
+
// ident: ID, move: <Move>
|
|
776
|
+
pub fn singleturn(self: Self, args: anytype) Error!void {
|
|
777
|
+
return single(self, .SingleTurn, args);
|
|
514
778
|
}
|
|
515
779
|
|
|
516
|
-
|
|
517
|
-
|
|
780
|
+
// ident: ID, move: <Move>
|
|
781
|
+
fn single(self: Self, arg: ArgType, args: anytype) Error!void {
|
|
782
|
+
if (!enabled) return;
|
|
783
|
+
|
|
518
784
|
try self.writer.writeAll(&.{
|
|
519
|
-
@
|
|
520
|
-
@
|
|
521
|
-
@
|
|
785
|
+
@intFromEnum(arg),
|
|
786
|
+
@as(u8, @bitCast(args[0])),
|
|
787
|
+
@intFromEnum(args[1]),
|
|
522
788
|
});
|
|
523
789
|
}
|
|
524
790
|
|
|
525
|
-
|
|
526
|
-
|
|
791
|
+
// weather: <Weather>, reason: Weather
|
|
792
|
+
pub fn weather(self: Self, args: anytype) Error!void {
|
|
793
|
+
if (!enabled) return;
|
|
794
|
+
|
|
795
|
+
assert(!(args[0] == .None and args[1] == .Upkeep));
|
|
527
796
|
try self.writer.writeAll(&.{
|
|
528
|
-
@
|
|
529
|
-
@
|
|
530
|
-
@
|
|
797
|
+
@intFromEnum(ArgType.Weather),
|
|
798
|
+
@intFromEnum(args[0]),
|
|
799
|
+
@intFromEnum(@as(Weather, args[1])),
|
|
531
800
|
});
|
|
532
801
|
}
|
|
533
802
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
803
|
+
// -
|
|
804
|
+
pub fn laststill(self: Self, _: anytype) Error!void {
|
|
805
|
+
if (!enabled) return;
|
|
806
|
+
|
|
807
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
|
|
537
808
|
}
|
|
538
809
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
810
|
+
// -
|
|
811
|
+
pub fn lastmiss(self: Self, _: anytype) Error!void {
|
|
812
|
+
if (!enabled) return;
|
|
813
|
+
|
|
814
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
|
|
542
815
|
}
|
|
543
816
|
};
|
|
544
817
|
}
|
|
545
818
|
|
|
819
|
+
/// `Log` type backed by the optimized `ByteStream.Writer`.
|
|
546
820
|
pub const FixedLog = Log(ByteStream.Writer);
|
|
547
821
|
|
|
822
|
+
/// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
|
|
823
|
+
/// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
|
|
824
|
+
/// should not be used for general purpose writing.
|
|
548
825
|
pub const ByteStream = struct {
|
|
549
826
|
buffer: []u8,
|
|
550
827
|
pos: usize = 0,
|
|
@@ -562,10 +839,10 @@ pub const ByteStream = struct {
|
|
|
562
839
|
try self.stream.writeByte(byte);
|
|
563
840
|
}
|
|
564
841
|
|
|
565
|
-
pub fn
|
|
842
|
+
pub fn writeInt(self: Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
|
|
566
843
|
// TODO: rework this to write directly to the buffer?
|
|
567
|
-
var bytes: [(@typeInfo(T)
|
|
568
|
-
std.mem.
|
|
844
|
+
var bytes: [@divExact(@field(@typeInfo(T), @tagName(Int)).bits, 8)]u8 = undefined;
|
|
845
|
+
std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(v)), &bytes, v, end);
|
|
569
846
|
return self.writeAll(&bytes);
|
|
570
847
|
}
|
|
571
848
|
};
|
|
@@ -585,15 +862,19 @@ pub const ByteStream = struct {
|
|
|
585
862
|
}
|
|
586
863
|
};
|
|
587
864
|
|
|
588
|
-
pub const Kind = enum { Move, Species, Type, Status };
|
|
589
|
-
pub const Formatter = fn (Kind, u8) []const u8;
|
|
865
|
+
pub const Kind = enum { Move, Species, Type, Status, Item, Weather };
|
|
590
866
|
|
|
591
|
-
pub fn format(
|
|
867
|
+
pub fn format(
|
|
868
|
+
gen: anytype,
|
|
869
|
+
a: []const u8,
|
|
870
|
+
b: ?[]const u8,
|
|
871
|
+
color: bool,
|
|
872
|
+
) void {
|
|
592
873
|
print("\n", .{});
|
|
593
874
|
|
|
594
875
|
var i: usize = 0;
|
|
595
876
|
while (i < a.len) {
|
|
596
|
-
const arg = @
|
|
877
|
+
const arg: ArgType = @enumFromInt(a[i]);
|
|
597
878
|
const name = switch (arg) {
|
|
598
879
|
.None => if (color) "\x1b[2m-\x1b[0m" else "-",
|
|
599
880
|
.LastStill => "|[still]",
|
|
@@ -626,6 +907,18 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
626
907
|
.Resisted => "|-resisted|",
|
|
627
908
|
.Immune => "|-immune|",
|
|
628
909
|
.Transform => "|-transform|",
|
|
910
|
+
.Drag => "|drag|",
|
|
911
|
+
.Item => "|-item|",
|
|
912
|
+
.EndItem => "|-enditem|",
|
|
913
|
+
.CureTeam => "|-cureteam|",
|
|
914
|
+
.SetHP => "|-sethp|",
|
|
915
|
+
.SetBoost => "|-setboost|",
|
|
916
|
+
.CopyBoost => "|-copyboost|",
|
|
917
|
+
.SideStart => "|-sidestart|",
|
|
918
|
+
.SideEnd => "|-sideend|",
|
|
919
|
+
.SingleMove => "|-singlemove|",
|
|
920
|
+
.SingleTurn => "|-singleturn|",
|
|
921
|
+
.Weather => "|-weather|",
|
|
629
922
|
else => unreachable,
|
|
630
923
|
};
|
|
631
924
|
printc("{s}", .{name}, a, b, &i, 1, color);
|
|
@@ -639,43 +932,53 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
639
932
|
.OHKO,
|
|
640
933
|
=> {},
|
|
641
934
|
.Move => {
|
|
642
|
-
const source = ID.from(@intCast(
|
|
935
|
+
const source = ID.from(@intCast(a[i]));
|
|
643
936
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
644
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
645
|
-
const target = ID.from(@intCast(
|
|
937
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
938
|
+
const target = ID.from(@intCast(a[i]));
|
|
646
939
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
647
|
-
const reason = @
|
|
940
|
+
const reason: Move = @enumFromInt(a[i]);
|
|
648
941
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
649
|
-
if (reason == .From)
|
|
942
|
+
if (reason == .From) {
|
|
943
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
944
|
+
}
|
|
650
945
|
},
|
|
651
|
-
.Switch => {
|
|
652
|
-
const id = ID.from(@intCast(
|
|
946
|
+
.Switch, .Drag => {
|
|
947
|
+
const id = ID.from(@intCast(a[i]));
|
|
653
948
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
654
|
-
printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color);
|
|
949
|
+
printc(" {s}", .{formatter(gen, .Species, a[i])}, a, b, &i, 1, color);
|
|
950
|
+
if (@hasDecl(gen, "Gender")) {
|
|
951
|
+
if (a[i] == N(gen.Gender.Unknown)) {
|
|
952
|
+
i += 1;
|
|
953
|
+
} else {
|
|
954
|
+
const gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
|
|
955
|
+
printc(", {s}", .{gender}, a, b, &i, 1, color);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
655
958
|
printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
|
|
656
959
|
switch (endian) {
|
|
657
|
-
|
|
960
|
+
big => {
|
|
658
961
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
659
962
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
660
963
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
661
964
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
662
965
|
},
|
|
663
|
-
|
|
966
|
+
little => {
|
|
664
967
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
665
968
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
666
969
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
667
970
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
668
971
|
},
|
|
669
972
|
}
|
|
670
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
973
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
671
974
|
},
|
|
672
975
|
.Cant => {
|
|
673
|
-
const id = ID.from(@intCast(
|
|
976
|
+
const id = ID.from(@intCast(a[i]));
|
|
674
977
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
675
|
-
const reason = @
|
|
978
|
+
const reason: Cant = @enumFromInt(a[i]);
|
|
676
979
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
677
980
|
if (reason == .Disable) {
|
|
678
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
981
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
679
982
|
}
|
|
680
983
|
},
|
|
681
984
|
.Faint,
|
|
@@ -684,124 +987,189 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
684
987
|
.Crit,
|
|
685
988
|
.SuperEffective,
|
|
686
989
|
.Resisted,
|
|
990
|
+
.CureTeam,
|
|
687
991
|
=> {
|
|
688
|
-
const id = ID.from(@intCast(
|
|
992
|
+
const id = ID.from(@intCast(a[i]));
|
|
689
993
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
690
994
|
},
|
|
691
995
|
.Turn => {
|
|
692
996
|
const turn = switch (endian) {
|
|
693
|
-
|
|
694
|
-
|
|
997
|
+
big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
|
|
998
|
+
little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
|
|
695
999
|
};
|
|
696
1000
|
printc(" {d}", .{turn}, a, b, &i, 2, color);
|
|
697
1001
|
},
|
|
698
|
-
.Win =>
|
|
1002
|
+
.Win => {
|
|
1003
|
+
printc(" {s}", .{@tagName(@as(Player, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1004
|
+
},
|
|
699
1005
|
.Damage, .Heal => {
|
|
700
|
-
var id = ID.from(@intCast(
|
|
1006
|
+
var id = ID.from(@intCast(a[i]));
|
|
701
1007
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
702
1008
|
switch (endian) {
|
|
703
|
-
|
|
1009
|
+
big => {
|
|
704
1010
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
705
1011
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
706
1012
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
707
1013
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
708
1014
|
},
|
|
709
|
-
|
|
1015
|
+
little => {
|
|
710
1016
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
711
1017
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
712
1018
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
713
1019
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
714
1020
|
},
|
|
715
1021
|
}
|
|
716
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1022
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
717
1023
|
if (arg == .Damage) {
|
|
718
|
-
const reason = a[i];
|
|
719
|
-
printc(" {s}", .{@tagName(
|
|
720
|
-
if (reason ==
|
|
721
|
-
id = ID.from(@intCast(
|
|
1024
|
+
const reason: Damage = @enumFromInt(a[i]);
|
|
1025
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1026
|
+
if (reason == .RecoilOf) {
|
|
1027
|
+
id = ID.from(@intCast(a[i]));
|
|
722
1028
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
723
1029
|
}
|
|
724
1030
|
} else {
|
|
725
|
-
const reason = @
|
|
1031
|
+
const reason: Heal = @enumFromInt(a[i]);
|
|
726
1032
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
727
1033
|
if (reason == .Drain) {
|
|
728
|
-
id = ID.from(@intCast(
|
|
1034
|
+
id = ID.from(@intCast(a[i]));
|
|
729
1035
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
730
1036
|
}
|
|
731
1037
|
}
|
|
732
1038
|
},
|
|
733
1039
|
.Status => {
|
|
734
|
-
const id = ID.from(@intCast(
|
|
1040
|
+
const id = ID.from(@intCast(a[i]));
|
|
735
1041
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
736
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
737
|
-
const reason = @
|
|
1042
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1043
|
+
const reason: Status = @enumFromInt(a[i]);
|
|
738
1044
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
739
|
-
if (reason == .From)
|
|
1045
|
+
if (reason == .From) {
|
|
1046
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1047
|
+
}
|
|
740
1048
|
},
|
|
741
1049
|
.CureStatus => {
|
|
742
|
-
const id = ID.from(@intCast(
|
|
1050
|
+
const id = ID.from(@intCast(a[i]));
|
|
743
1051
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
744
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
745
|
-
|
|
1052
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1053
|
+
const reason: CureStatus = @enumFromInt(a[i]);
|
|
1054
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
746
1055
|
},
|
|
747
1056
|
.Boost => {
|
|
748
|
-
const id = ID.from(@intCast(
|
|
1057
|
+
const id = ID.from(@intCast(a[i]));
|
|
749
1058
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
750
|
-
printc(" {s}", .{@tagName(@
|
|
1059
|
+
printc(" {s}", .{@tagName(@as(Boost, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
751
1060
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
752
1061
|
},
|
|
753
1062
|
.Fail => {
|
|
754
|
-
const id = ID.from(@intCast(
|
|
1063
|
+
const id = ID.from(@intCast(a[i]));
|
|
755
1064
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
756
|
-
printc(" {s}", .{@tagName(@
|
|
1065
|
+
printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
757
1066
|
},
|
|
758
|
-
.HitCount => {
|
|
759
|
-
const id = ID.from(@intCast(
|
|
1067
|
+
.HitCount, .SetBoost => {
|
|
1068
|
+
const id = ID.from(@intCast(a[i]));
|
|
760
1069
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
761
1070
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
762
1071
|
},
|
|
763
|
-
.Prepare => {
|
|
764
|
-
const id = ID.from(@intCast(
|
|
1072
|
+
.Prepare, .SingleMove, .SingleTurn => {
|
|
1073
|
+
const id = ID.from(@intCast(a[i]));
|
|
765
1074
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
766
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1075
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
767
1076
|
},
|
|
768
1077
|
.Activate => {
|
|
769
|
-
const id = ID.from(@intCast(
|
|
1078
|
+
const id = ID.from(@intCast(a[i]));
|
|
770
1079
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
771
|
-
|
|
1080
|
+
const reason: Activate = @enumFromInt(a[i]);
|
|
1081
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1082
|
+
if (reason == .SubstituteBlock) {
|
|
1083
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1084
|
+
} else if (reason == .Magnitude) {
|
|
1085
|
+
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
1086
|
+
}
|
|
772
1087
|
},
|
|
773
1088
|
.Start => {
|
|
774
|
-
const id = ID.from(@intCast(
|
|
1089
|
+
const id = ID.from(@intCast(a[i]));
|
|
775
1090
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
776
1091
|
const reason = a[i];
|
|
777
|
-
printc(" {s}", .{@tagName(@
|
|
778
|
-
if (@
|
|
779
|
-
|
|
1092
|
+
printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
|
|
1093
|
+
if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
|
|
1094
|
+
// FIXME
|
|
1095
|
+
const types = @as(gen1.Types, @bitCast(a[i]));
|
|
780
1096
|
const args = .{
|
|
781
|
-
formatter(.Type, @
|
|
782
|
-
formatter(.Type, @
|
|
1097
|
+
formatter(gen, .Type, @intFromEnum(types.type1)),
|
|
1098
|
+
formatter(gen, .Type, @intFromEnum(types.type2)),
|
|
783
1099
|
};
|
|
784
1100
|
printc(" {s}/{s}", args, a, b, &i, 1, color);
|
|
785
|
-
} else if (reason >= @
|
|
786
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1101
|
+
} else if (reason >= @intFromEnum(Start.Disable)) {
|
|
1102
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
787
1103
|
}
|
|
788
1104
|
},
|
|
789
1105
|
.End => {
|
|
790
|
-
const id = ID.from(@intCast(
|
|
1106
|
+
const id = ID.from(@intCast(a[i]));
|
|
791
1107
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
792
|
-
printc(" {s}", .{@tagName(@
|
|
1108
|
+
printc(" {s}", .{@tagName(@as(End, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
793
1109
|
},
|
|
794
1110
|
.Immune => {
|
|
795
|
-
const id = ID.from(@intCast(
|
|
1111
|
+
const id = ID.from(@intCast(a[i]));
|
|
796
1112
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
797
|
-
printc(" {s}", .{@tagName(@
|
|
1113
|
+
printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
798
1114
|
},
|
|
799
|
-
.Transform => {
|
|
800
|
-
const source = ID.from(@intCast(
|
|
1115
|
+
.Transform, .CopyBoost => {
|
|
1116
|
+
const source = ID.from(@intCast(a[i]));
|
|
801
1117
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
802
|
-
const target = ID.from(@intCast(
|
|
1118
|
+
const target = ID.from(@intCast(a[i]));
|
|
803
1119
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
804
1120
|
},
|
|
1121
|
+
.Item, .EndItem => {
|
|
1122
|
+
var id = ID.from(@intCast(a[i]));
|
|
1123
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1124
|
+
printc(" {s}", .{formatter(gen, .Item, a[i])}, a, b, &i, 1, color);
|
|
1125
|
+
if (arg == .Item) {
|
|
1126
|
+
id = ID.from(@intCast(a[i]));
|
|
1127
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1128
|
+
} else {
|
|
1129
|
+
const reason: EndItem = @enumFromInt(a[i]);
|
|
1130
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1131
|
+
}
|
|
1132
|
+
},
|
|
1133
|
+
.SetHP => {
|
|
1134
|
+
const id = ID.from(@intCast(a[i]));
|
|
1135
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1136
|
+
switch (endian) {
|
|
1137
|
+
big => {
|
|
1138
|
+
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1139
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1140
|
+
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1141
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1142
|
+
},
|
|
1143
|
+
little => {
|
|
1144
|
+
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1145
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1146
|
+
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1147
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1148
|
+
},
|
|
1149
|
+
}
|
|
1150
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1151
|
+
printc(" {s}", .{@tagName(@as(SetHP, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1152
|
+
},
|
|
1153
|
+
.SideStart => {
|
|
1154
|
+
const id = ID.from(@intCast(a[i]));
|
|
1155
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1156
|
+
printc(" {s}", .{@tagName(@as(Side, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1157
|
+
},
|
|
1158
|
+
.SideEnd => {
|
|
1159
|
+
var id = ID.from(@intCast(a[i]));
|
|
1160
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1161
|
+
const reason: Side = @enumFromInt(a[i]);
|
|
1162
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1163
|
+
if (reason == .Spikes) {
|
|
1164
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1165
|
+
id = ID.from(@intCast(a[i]));
|
|
1166
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1167
|
+
}
|
|
1168
|
+
},
|
|
1169
|
+
.Weather => {
|
|
1170
|
+
printc(" {s}", .{formatter(gen, .Weather, a[i])}, a, b, &i, 1, color);
|
|
1171
|
+
printc(" {s}", .{@tagName(@as(Weather, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1172
|
+
},
|
|
805
1173
|
else => unreachable,
|
|
806
1174
|
}
|
|
807
1175
|
print("\n", .{});
|
|
@@ -833,26 +1201,24 @@ fn printc(
|
|
|
833
1201
|
}
|
|
834
1202
|
|
|
835
1203
|
pub fn expectLog(
|
|
836
|
-
comptime
|
|
1204
|
+
comptime gen: anytype,
|
|
837
1205
|
expected: []const u8,
|
|
838
1206
|
actual: []const u8,
|
|
839
1207
|
offset: usize,
|
|
840
1208
|
) !void {
|
|
841
|
-
if (!
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
break :color std.io.getStdErr().supportsAnsiEscapeCodes();
|
|
849
|
-
}
|
|
1209
|
+
if (!enabled) return;
|
|
1210
|
+
|
|
1211
|
+
const color = if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR"))
|
|
1212
|
+
true
|
|
1213
|
+
else switch (std.io.tty.detectConfig(std.io.getStdErr())) {
|
|
1214
|
+
.escape_codes => true,
|
|
1215
|
+
else => false,
|
|
850
1216
|
};
|
|
851
1217
|
|
|
852
1218
|
expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
|
|
853
1219
|
error.TestExpectedEqual => {
|
|
854
|
-
format(
|
|
855
|
-
format(
|
|
1220
|
+
format(gen, expected, null, color);
|
|
1221
|
+
format(gen, actual, expected, color);
|
|
856
1222
|
return err;
|
|
857
1223
|
},
|
|
858
1224
|
else => return err,
|
|
@@ -878,63 +1244,75 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
|
|
|
878
1244
|
}
|
|
879
1245
|
}
|
|
880
1246
|
|
|
881
|
-
const endian = builtin.target.cpu.arch.endian();
|
|
882
|
-
|
|
883
1247
|
fn N(e: anytype) u8 {
|
|
884
|
-
return @
|
|
1248
|
+
return @intFromEnum(e);
|
|
885
1249
|
}
|
|
886
1250
|
|
|
887
1251
|
const p1 = Player.P1;
|
|
888
1252
|
const p2 = Player.P2;
|
|
889
1253
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
pub const helpers = @import("../gen1/helpers.zig");
|
|
893
|
-
};
|
|
894
|
-
|
|
895
|
-
var buf: [gen1.LOGS_SIZE]u8 = undefined;
|
|
896
|
-
var stream = ByteStream{ .buffer = &buf };
|
|
1254
|
+
var buf: [pkmn.LOGS_SIZE]u8 = undefined;
|
|
1255
|
+
var stream: ByteStream = .{ .buffer = &buf };
|
|
897
1256
|
var log: FixedLog = .{ .writer = stream.writer() };
|
|
898
1257
|
|
|
899
|
-
const
|
|
900
|
-
const
|
|
1258
|
+
const gen1 = pkmn.gen1;
|
|
1259
|
+
const gen2 = pkmn.gen2;
|
|
1260
|
+
|
|
1261
|
+
const M1 = gen1.Move;
|
|
1262
|
+
const S1 = gen1.Species;
|
|
1263
|
+
|
|
1264
|
+
const M2 = gen2.Move;
|
|
1265
|
+
const S2 = gen2.Species;
|
|
1266
|
+
const I2 = gen2.Item;
|
|
1267
|
+
const W2 = gen2.Weather;
|
|
901
1268
|
|
|
902
1269
|
fn expectLog1(expected: []const u8, actual: []const u8) !void {
|
|
903
|
-
return expectLog(
|
|
1270
|
+
return expectLog(gen1, expected, actual, 0);
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
fn expectLog2(expected: []const u8, actual: []const u8) !void {
|
|
1274
|
+
return expectLog(gen2, expected, actual, 0);
|
|
904
1275
|
}
|
|
905
1276
|
|
|
906
|
-
fn
|
|
1277
|
+
fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
|
|
907
1278
|
return switch (kind) {
|
|
908
|
-
.Move => @tagName(@
|
|
909
|
-
.Species => @tagName(@
|
|
910
|
-
.Type => @tagName(@
|
|
911
|
-
.Status =>
|
|
1279
|
+
.Move => @tagName(@as(gen.Move, @enumFromInt(byte))),
|
|
1280
|
+
.Species => @tagName(@as(gen.Species, @enumFromInt(byte))),
|
|
1281
|
+
.Type => @tagName(@as(gen.Type, @enumFromInt(byte))),
|
|
1282
|
+
.Status => gen.Status.name(byte),
|
|
1283
|
+
.Item => if (@hasDecl(gen, "Item"))
|
|
1284
|
+
@tagName(@as(gen.Item, @enumFromInt(byte)))
|
|
1285
|
+
else
|
|
1286
|
+
unreachable,
|
|
1287
|
+
.Weather => if (@hasDecl(gen, "Weather"))
|
|
1288
|
+
@tagName(@as(gen.Weather, @enumFromInt(byte)))
|
|
1289
|
+
else
|
|
1290
|
+
unreachable,
|
|
912
1291
|
};
|
|
913
1292
|
}
|
|
914
1293
|
|
|
915
1294
|
test "|move|" {
|
|
916
|
-
try log.move(p2.ident(4),
|
|
1295
|
+
try log.move(.{ p2.ident(4), M1.Thunderbolt, p1.ident(5) });
|
|
917
1296
|
try expectLog1(
|
|
918
|
-
&.{ N(ArgType.Move), 0b1100, N(
|
|
1297
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
|
|
919
1298
|
buf[0..5],
|
|
920
1299
|
);
|
|
921
1300
|
stream.reset();
|
|
922
1301
|
|
|
923
|
-
try log.move(p2.ident(4),
|
|
924
|
-
const wrap = N(M.Wrap);
|
|
1302
|
+
try log.move(.{ p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome });
|
|
925
1303
|
try expectLog1(
|
|
926
|
-
&.{ N(ArgType.Move), 0b1100,
|
|
1304
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
|
|
927
1305
|
buf[0..6],
|
|
928
1306
|
);
|
|
929
1307
|
stream.reset();
|
|
930
1308
|
|
|
931
|
-
try log.move(p2.ident(4),
|
|
932
|
-
try log.laststill();
|
|
1309
|
+
try log.move(.{ p2.ident(4), M1.SkullBash, ID{} });
|
|
1310
|
+
try log.laststill(.{});
|
|
933
1311
|
try expectLog1(
|
|
934
1312
|
&.{
|
|
935
1313
|
N(ArgType.Move),
|
|
936
1314
|
0b1100,
|
|
937
|
-
N(
|
|
1315
|
+
N(M1.SkullBash),
|
|
938
1316
|
0,
|
|
939
1317
|
N(Move.None),
|
|
940
1318
|
N(ArgType.LastStill),
|
|
@@ -943,13 +1321,13 @@ test "|move|" {
|
|
|
943
1321
|
);
|
|
944
1322
|
stream.reset();
|
|
945
1323
|
|
|
946
|
-
try log.move(p2.ident(4),
|
|
947
|
-
try log.lastmiss();
|
|
1324
|
+
try log.move(.{ p2.ident(4), M1.Tackle, p1.ident(5) });
|
|
1325
|
+
try log.lastmiss(.{});
|
|
948
1326
|
try expectLog1(
|
|
949
1327
|
&.{
|
|
950
1328
|
N(ArgType.Move),
|
|
951
1329
|
0b1100,
|
|
952
|
-
N(
|
|
1330
|
+
N(M1.Tackle),
|
|
953
1331
|
0b0101,
|
|
954
1332
|
N(Move.None),
|
|
955
1333
|
N(ArgType.LastMiss),
|
|
@@ -965,11 +1343,11 @@ test "|switch|" {
|
|
|
965
1343
|
snorlax.hp = 200;
|
|
966
1344
|
snorlax.stats.hp = 400;
|
|
967
1345
|
snorlax.status = gen1.Status.init(.PAR);
|
|
968
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1346
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
969
1347
|
const par = 0b1000000;
|
|
970
1348
|
var expected: []const u8 = switch (endian) {
|
|
971
|
-
|
|
972
|
-
|
|
1349
|
+
big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
|
|
1350
|
+
little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
|
|
973
1351
|
};
|
|
974
1352
|
try expectLog1(expected, buf[0..9]);
|
|
975
1353
|
stream.reset();
|
|
@@ -977,62 +1355,81 @@ test "|switch|" {
|
|
|
977
1355
|
snorlax.level = 100;
|
|
978
1356
|
snorlax.hp = 0;
|
|
979
1357
|
snorlax.status = 0;
|
|
980
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1358
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
981
1359
|
expected = switch (endian) {
|
|
982
|
-
|
|
983
|
-
|
|
1360
|
+
big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
|
|
1361
|
+
little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
|
|
984
1362
|
};
|
|
985
1363
|
try expectLog1(expected, buf[0..9]);
|
|
986
1364
|
stream.reset();
|
|
987
1365
|
|
|
988
1366
|
snorlax.hp = 400;
|
|
989
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1367
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
990
1368
|
expected = switch (endian) {
|
|
991
|
-
|
|
992
|
-
|
|
1369
|
+
big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
|
|
1370
|
+
little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
|
|
993
1371
|
};
|
|
994
1372
|
try expectLog1(expected, buf[0..9]);
|
|
995
1373
|
stream.reset();
|
|
1374
|
+
|
|
1375
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1376
|
+
blissey.level = 91;
|
|
1377
|
+
blissey.hp = 200;
|
|
1378
|
+
blissey.stats.hp = 400;
|
|
1379
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1380
|
+
try log.switched(.{ p2.ident(3), &blissey });
|
|
1381
|
+
expected = &(.{
|
|
1382
|
+
N(ArgType.Switch),
|
|
1383
|
+
0b1011,
|
|
1384
|
+
N(S2.Blissey),
|
|
1385
|
+
N(gen2.Gender.Female),
|
|
1386
|
+
91,
|
|
1387
|
+
} ++ switch (endian) {
|
|
1388
|
+
big => .{ 0, 200, 1, 144, par },
|
|
1389
|
+
little => .{ 200, 0, 144, 1, par },
|
|
1390
|
+
});
|
|
1391
|
+
try expectLog2(expected, buf[0..10]);
|
|
1392
|
+
stream.reset();
|
|
996
1393
|
}
|
|
997
1394
|
|
|
998
1395
|
test "|cant|" {
|
|
999
|
-
try log.cant(p2.ident(6), .Bound);
|
|
1396
|
+
try log.cant(.{ p2.ident(6), .Bound });
|
|
1000
1397
|
try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
|
|
1001
1398
|
stream.reset();
|
|
1002
1399
|
|
|
1003
|
-
try log.
|
|
1004
|
-
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(
|
|
1400
|
+
try log.cant(.{ p1.ident(2), .Disable, M1.Earthquake });
|
|
1401
|
+
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
|
|
1005
1402
|
stream.reset();
|
|
1006
1403
|
}
|
|
1007
1404
|
|
|
1008
1405
|
test "|faint|" {
|
|
1009
|
-
try log.faint(p2.ident(2), false);
|
|
1406
|
+
try log.faint(.{ p2.ident(2), false });
|
|
1010
1407
|
try expectLog1(&.{ N(ArgType.Faint), 0b1010 }, buf[0..2]);
|
|
1011
1408
|
stream.reset();
|
|
1012
1409
|
|
|
1013
|
-
try log.faint(p2.ident(2), true);
|
|
1410
|
+
try log.faint(.{ p2.ident(2), true });
|
|
1014
1411
|
try expectLog1(&.{ N(ArgType.Faint), 0b1010, N(ArgType.None) }, buf[0..3]);
|
|
1015
1412
|
stream.reset();
|
|
1016
1413
|
}
|
|
1017
1414
|
|
|
1018
1415
|
test "|turn|" {
|
|
1019
|
-
try log.turn(42);
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1416
|
+
try log.turn(.{42});
|
|
1417
|
+
const expected = switch (endian) {
|
|
1418
|
+
big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
|
|
1419
|
+
little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
|
|
1023
1420
|
};
|
|
1024
1421
|
try expectLog1(expected, buf[0..4]);
|
|
1025
1422
|
stream.reset();
|
|
1026
1423
|
}
|
|
1027
1424
|
|
|
1028
1425
|
test "|win|" {
|
|
1029
|
-
try log.win(.P2);
|
|
1426
|
+
try log.win(.{.P2});
|
|
1030
1427
|
try expectLog1(&.{ N(ArgType.Win), 1, N(ArgType.None) }, buf[0..3]);
|
|
1031
1428
|
stream.reset();
|
|
1032
1429
|
}
|
|
1033
1430
|
|
|
1034
1431
|
test "|tie|" {
|
|
1035
|
-
try log.tie();
|
|
1432
|
+
try log.tie(.{});
|
|
1036
1433
|
try expectLog1(&.{ N(ArgType.Tie), N(ArgType.None) }, buf[0..2]);
|
|
1037
1434
|
stream.reset();
|
|
1038
1435
|
}
|
|
@@ -1041,10 +1438,10 @@ test "|-damage|" {
|
|
|
1041
1438
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1042
1439
|
chansey.hp = 612;
|
|
1043
1440
|
chansey.status = gen1.Status.slp(1);
|
|
1044
|
-
try log.damage(p2.ident(2), &chansey, .None);
|
|
1441
|
+
try log.damage(.{ p2.ident(2), &chansey, .None });
|
|
1045
1442
|
var expected: []const u8 = switch (endian) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1443
|
+
big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
|
|
1444
|
+
little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
|
|
1048
1445
|
};
|
|
1049
1446
|
try expectLog1(expected, buf[0..8]);
|
|
1050
1447
|
stream.reset();
|
|
@@ -1052,19 +1449,19 @@ test "|-damage|" {
|
|
|
1052
1449
|
chansey.hp = 100;
|
|
1053
1450
|
chansey.stats.hp = 256;
|
|
1054
1451
|
chansey.status = 0;
|
|
1055
|
-
try log.damage(p2.ident(2), &chansey, .Confusion);
|
|
1452
|
+
try log.damage(.{ p2.ident(2), &chansey, .Confusion });
|
|
1056
1453
|
expected = switch (endian) {
|
|
1057
|
-
|
|
1058
|
-
|
|
1454
|
+
big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
|
|
1455
|
+
little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
|
|
1059
1456
|
};
|
|
1060
1457
|
try expectLog1(expected, buf[0..8]);
|
|
1061
1458
|
stream.reset();
|
|
1062
1459
|
|
|
1063
1460
|
chansey.status = gen1.Status.init(.PSN);
|
|
1064
|
-
try log.
|
|
1461
|
+
try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
|
|
1065
1462
|
expected = switch (endian) {
|
|
1066
|
-
|
|
1067
|
-
|
|
1463
|
+
big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1464
|
+
little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1068
1465
|
};
|
|
1069
1466
|
try expectLog1(expected, buf[0..9]);
|
|
1070
1467
|
stream.reset();
|
|
@@ -1074,10 +1471,10 @@ test "|-heal|" {
|
|
|
1074
1471
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1075
1472
|
chansey.hp = 612;
|
|
1076
1473
|
chansey.status = gen1.Status.slp(1);
|
|
1077
|
-
try log.heal(p2.ident(2), &chansey, .None);
|
|
1474
|
+
try log.heal(.{ p2.ident(2), &chansey, .None });
|
|
1078
1475
|
var expected: []const u8 = switch (endian) {
|
|
1079
|
-
|
|
1080
|
-
|
|
1476
|
+
big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
|
|
1477
|
+
little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
|
|
1081
1478
|
};
|
|
1082
1479
|
try expectLog1(expected, buf[0..8]);
|
|
1083
1480
|
stream.reset();
|
|
@@ -1085,46 +1482,46 @@ test "|-heal|" {
|
|
|
1085
1482
|
chansey.hp = 100;
|
|
1086
1483
|
chansey.stats.hp = 256;
|
|
1087
1484
|
chansey.status = 0;
|
|
1088
|
-
try log.heal(p2.ident(2), &chansey, .Silent);
|
|
1485
|
+
try log.heal(.{ p2.ident(2), &chansey, .Silent });
|
|
1089
1486
|
expected = switch (endian) {
|
|
1090
|
-
|
|
1091
|
-
|
|
1487
|
+
big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
|
|
1488
|
+
little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
|
|
1092
1489
|
};
|
|
1093
1490
|
try expectLog1(expected, buf[0..8]);
|
|
1094
1491
|
stream.reset();
|
|
1095
1492
|
|
|
1096
|
-
try log.
|
|
1493
|
+
try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
|
|
1097
1494
|
expected = switch (endian) {
|
|
1098
|
-
|
|
1099
|
-
|
|
1495
|
+
big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
|
|
1496
|
+
little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
|
|
1100
1497
|
};
|
|
1101
1498
|
try expectLog1(expected, buf[0..9]);
|
|
1102
1499
|
stream.reset();
|
|
1103
1500
|
}
|
|
1104
1501
|
|
|
1105
1502
|
test "|-status|" {
|
|
1106
|
-
try log.status(p2.ident(6), gen1.Status.init(.BRN), .None);
|
|
1503
|
+
try log.status(.{ p2.ident(6), gen1.Status.init(.BRN), .None });
|
|
1107
1504
|
try expectLog1(&.{ N(ArgType.Status), 0b1110, 0b10000, N(Status.None) }, buf[0..4]);
|
|
1108
1505
|
stream.reset();
|
|
1109
1506
|
|
|
1110
|
-
try log.status(p2.ident(2), gen1.Status.init(.PSN), .Silent);
|
|
1507
|
+
try log.status(.{ p2.ident(2), gen1.Status.init(.PSN), .Silent });
|
|
1111
1508
|
try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
|
|
1112
1509
|
stream.reset();
|
|
1113
1510
|
|
|
1114
|
-
try log.
|
|
1511
|
+
try log.status(.{ p1.ident(1), gen1.Status.init(.PAR), .From, M1.BodySlam });
|
|
1115
1512
|
try expectLog1(
|
|
1116
|
-
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(
|
|
1513
|
+
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
|
|
1117
1514
|
buf[0..5],
|
|
1118
1515
|
);
|
|
1119
1516
|
stream.reset();
|
|
1120
1517
|
}
|
|
1121
1518
|
|
|
1122
1519
|
test "|-curestatus|" {
|
|
1123
|
-
try log.curestatus(p2.ident(6), gen1.Status.slp(7), .Message);
|
|
1520
|
+
try log.curestatus(.{ p2.ident(6), gen1.Status.slp(7), .Message });
|
|
1124
1521
|
try expectLog1(&.{ N(ArgType.CureStatus), 0b1110, 0b111, N(CureStatus.Message) }, buf[0..4]);
|
|
1125
1522
|
stream.reset();
|
|
1126
1523
|
|
|
1127
|
-
try log.curestatus(p1.ident(2), gen1.Status.TOX, .Silent);
|
|
1524
|
+
try log.curestatus(.{ p1.ident(2), gen1.Status.TOX, .Silent });
|
|
1128
1525
|
try expectLog1(&.{
|
|
1129
1526
|
N(ArgType.CureStatus),
|
|
1130
1527
|
0b0010,
|
|
@@ -1135,163 +1532,306 @@ test "|-curestatus|" {
|
|
|
1135
1532
|
}
|
|
1136
1533
|
|
|
1137
1534
|
test "|-boost|" {
|
|
1138
|
-
try log.boost(p2.ident(6), .Speed, 2);
|
|
1535
|
+
try log.boost(.{ p2.ident(6), .Speed, 2 });
|
|
1139
1536
|
try expectLog1(&.{ N(ArgType.Boost), 0b1110, N(Boost.Speed), 8 }, buf[0..4]);
|
|
1140
1537
|
stream.reset();
|
|
1141
1538
|
|
|
1142
|
-
try log.boost(p1.ident(2), .Rage, 1);
|
|
1539
|
+
try log.boost(.{ p1.ident(2), .Rage, 1 });
|
|
1143
1540
|
try expectLog1(&.{ N(ArgType.Boost), 0b0010, N(Boost.Rage), 7 }, buf[0..4]);
|
|
1144
1541
|
stream.reset();
|
|
1145
1542
|
|
|
1146
|
-
try log.boost(p2.ident(3), .Defense, -2);
|
|
1543
|
+
try log.boost(.{ p2.ident(3), .Defense, -2 });
|
|
1147
1544
|
try expectLog1(&.{ N(ArgType.Boost), 0b1011, N(Boost.Defense), 4 }, buf[0..4]);
|
|
1148
1545
|
stream.reset();
|
|
1149
1546
|
}
|
|
1150
1547
|
|
|
1151
1548
|
test "|-clearallboost|" {
|
|
1152
|
-
try log.clearallboost();
|
|
1549
|
+
try log.clearallboost(.{});
|
|
1153
1550
|
try expectLog1(&.{N(ArgType.ClearAllBoost)}, buf[0..1]);
|
|
1154
1551
|
stream.reset();
|
|
1155
1552
|
}
|
|
1156
1553
|
|
|
1157
1554
|
test "|-fail|" {
|
|
1158
|
-
try log.fail(p2.ident(6), .None);
|
|
1555
|
+
try log.fail(.{ p2.ident(6), .None });
|
|
1159
1556
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.None) }, buf[0..3]);
|
|
1160
1557
|
stream.reset();
|
|
1161
1558
|
|
|
1162
|
-
try log.fail(p2.ident(6), .Sleep);
|
|
1559
|
+
try log.fail(.{ p2.ident(6), .Sleep });
|
|
1163
1560
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Sleep) }, buf[0..3]);
|
|
1164
1561
|
stream.reset();
|
|
1165
1562
|
|
|
1166
|
-
try log.fail(p2.ident(6), .Substitute);
|
|
1563
|
+
try log.fail(.{ p2.ident(6), .Substitute });
|
|
1167
1564
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Substitute) }, buf[0..3]);
|
|
1168
1565
|
stream.reset();
|
|
1169
1566
|
|
|
1170
|
-
try log.fail(p2.ident(6), .Weak);
|
|
1567
|
+
try log.fail(.{ p2.ident(6), .Weak });
|
|
1171
1568
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Weak) }, buf[0..3]);
|
|
1172
1569
|
stream.reset();
|
|
1173
1570
|
}
|
|
1174
1571
|
|
|
1175
1572
|
test "|-miss|" {
|
|
1176
|
-
try log.miss(p2.ident(4));
|
|
1573
|
+
try log.miss(.{p2.ident(4)});
|
|
1177
1574
|
try expectLog1(&.{ N(ArgType.Miss), 0b1100 }, buf[0..2]);
|
|
1178
1575
|
stream.reset();
|
|
1179
1576
|
}
|
|
1180
1577
|
test "|-hitcount|" {
|
|
1181
|
-
try log.hitcount(p2.ident(1), 5);
|
|
1578
|
+
try log.hitcount(.{ p2.ident(1), 5 });
|
|
1182
1579
|
try expectLog1(&.{ N(ArgType.HitCount), 0b1001, 5 }, buf[0..3]);
|
|
1183
1580
|
stream.reset();
|
|
1184
1581
|
}
|
|
1185
1582
|
|
|
1186
1583
|
test "|-prepare|" {
|
|
1187
|
-
try log.prepare(p2.ident(2),
|
|
1188
|
-
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(
|
|
1584
|
+
try log.prepare(.{ p2.ident(2), M1.Dig });
|
|
1585
|
+
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
|
|
1189
1586
|
stream.reset();
|
|
1190
1587
|
}
|
|
1191
1588
|
|
|
1192
1589
|
test "|-mustrecharge|" {
|
|
1193
|
-
try log.mustrecharge(p1.ident(6));
|
|
1590
|
+
try log.mustrecharge(.{p1.ident(6)});
|
|
1194
1591
|
try expectLog1(&.{ N(ArgType.MustRecharge), 0b0110 }, buf[0..2]);
|
|
1195
1592
|
stream.reset();
|
|
1196
1593
|
}
|
|
1197
1594
|
|
|
1198
1595
|
test "|-activate|" {
|
|
1199
|
-
try log.activate(p1.ident(2), .Struggle);
|
|
1596
|
+
try log.activate(.{ p1.ident(2), .Struggle });
|
|
1200
1597
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Struggle) }, buf[0..3]);
|
|
1201
1598
|
stream.reset();
|
|
1202
1599
|
|
|
1203
|
-
try log.activate(p2.ident(4), .Mist);
|
|
1600
|
+
try log.activate(.{ p2.ident(4), .Mist });
|
|
1204
1601
|
try expectLog1(&.{ N(ArgType.Activate), 0b1100, N(Activate.Mist) }, buf[0..3]);
|
|
1205
1602
|
stream.reset();
|
|
1206
1603
|
|
|
1207
|
-
try log.activate(p2.ident(6), .Substitute);
|
|
1604
|
+
try log.activate(.{ p2.ident(6), .Substitute });
|
|
1208
1605
|
try expectLog1(&.{ N(ArgType.Activate), 0b1110, N(Activate.Substitute) }, buf[0..3]);
|
|
1209
1606
|
stream.reset();
|
|
1210
1607
|
|
|
1211
|
-
try log.activate(p1.ident(2), .Splash);
|
|
1608
|
+
try log.activate(.{ p1.ident(2), .Splash });
|
|
1212
1609
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
|
|
1213
1610
|
stream.reset();
|
|
1611
|
+
|
|
1612
|
+
try log.activate(.{ p1.ident(4), .SubstituteBlock, M2.Spite });
|
|
1613
|
+
try expectLog1(&.{
|
|
1614
|
+
N(ArgType.Activate),
|
|
1615
|
+
0b0100,
|
|
1616
|
+
N(Activate.SubstituteBlock),
|
|
1617
|
+
N(M2.Spite),
|
|
1618
|
+
}, buf[0..4]);
|
|
1619
|
+
stream.reset();
|
|
1620
|
+
|
|
1621
|
+
try log.activate(.{ p1.ident(3), .Magnitude, 5 });
|
|
1622
|
+
try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
|
|
1623
|
+
stream.reset();
|
|
1214
1624
|
}
|
|
1215
1625
|
|
|
1216
1626
|
test "|-fieldactivate|" {
|
|
1217
|
-
try log.fieldactivate();
|
|
1627
|
+
try log.fieldactivate(.{});
|
|
1218
1628
|
try expectLog1(&.{N(ArgType.FieldActivate)}, buf[0..1]);
|
|
1219
1629
|
stream.reset();
|
|
1220
1630
|
}
|
|
1221
1631
|
|
|
1222
1632
|
test "|-start|" {
|
|
1223
|
-
try log.start(p2.ident(6), .Bide);
|
|
1633
|
+
try log.start(.{ p2.ident(6), .Bide });
|
|
1224
1634
|
try expectLog1(&.{ N(ArgType.Start), 0b1110, N(Start.Bide) }, buf[0..3]);
|
|
1225
1635
|
stream.reset();
|
|
1226
1636
|
|
|
1227
|
-
try log.start(p1.ident(2), .ConfusionSilent);
|
|
1637
|
+
try log.start(.{ p1.ident(2), .ConfusionSilent });
|
|
1228
1638
|
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.ConfusionSilent) }, buf[0..3]);
|
|
1229
1639
|
stream.reset();
|
|
1230
1640
|
|
|
1231
|
-
try log.
|
|
1641
|
+
try log.start(.{
|
|
1642
|
+
p2.ident(6),
|
|
1643
|
+
.TypeChange,
|
|
1644
|
+
gen1.Types{ .type1 = .Fire, .type2 = .Fire },
|
|
1645
|
+
p2.ident(5),
|
|
1646
|
+
});
|
|
1232
1647
|
try expectLog1(
|
|
1233
1648
|
&.{ N(ArgType.Start), 0b1110, N(Start.TypeChange), 0b1000_1000, 0b1101 },
|
|
1234
1649
|
buf[0..5],
|
|
1235
1650
|
);
|
|
1236
1651
|
stream.reset();
|
|
1237
1652
|
|
|
1238
|
-
try log.
|
|
1653
|
+
try log.start(.{
|
|
1654
|
+
p1.ident(2),
|
|
1655
|
+
.TypeChange,
|
|
1656
|
+
gen1.Types{ .type1 = .Bug, .type2 = .Poison },
|
|
1657
|
+
p2.ident(4),
|
|
1658
|
+
});
|
|
1239
1659
|
try expectLog1(
|
|
1240
1660
|
&.{ N(ArgType.Start), 0b0010, N(Start.TypeChange), 0b0011_0110, 0b1100 },
|
|
1241
1661
|
buf[0..5],
|
|
1242
1662
|
);
|
|
1243
1663
|
stream.reset();
|
|
1244
1664
|
|
|
1245
|
-
try log.
|
|
1246
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(
|
|
1665
|
+
try log.start(.{ p1.ident(2), .Disable, M1.Surf });
|
|
1666
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
|
|
1247
1667
|
stream.reset();
|
|
1248
1668
|
|
|
1249
|
-
try log.
|
|
1250
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(
|
|
1669
|
+
try log.start(.{ p1.ident(2), .Mimic, M1.Surf });
|
|
1670
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
|
|
1251
1671
|
stream.reset();
|
|
1252
1672
|
}
|
|
1253
1673
|
|
|
1254
1674
|
test "|-end|" {
|
|
1255
|
-
try log.end(p2.ident(6), .Bide);
|
|
1675
|
+
try log.end(.{ p2.ident(6), .Bide });
|
|
1256
1676
|
try expectLog1(&.{ N(ArgType.End), 0b1110, N(End.Bide) }, buf[0..3]);
|
|
1257
1677
|
stream.reset();
|
|
1258
1678
|
|
|
1259
|
-
try log.end(p1.ident(2), .ConfusionSilent);
|
|
1679
|
+
try log.end(.{ p1.ident(2), .ConfusionSilent });
|
|
1260
1680
|
try expectLog1(&.{ N(ArgType.End), 0b0010, N(End.ConfusionSilent) }, buf[0..3]);
|
|
1261
1681
|
stream.reset();
|
|
1262
1682
|
}
|
|
1263
1683
|
|
|
1264
1684
|
test "|-ohko|" {
|
|
1265
|
-
try log.ohko();
|
|
1685
|
+
try log.ohko(.{});
|
|
1266
1686
|
try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
|
|
1267
1687
|
stream.reset();
|
|
1268
1688
|
}
|
|
1689
|
+
|
|
1269
1690
|
test "|-crit|" {
|
|
1270
|
-
try log.crit(p2.ident(5));
|
|
1691
|
+
try log.crit(.{p2.ident(5)});
|
|
1271
1692
|
try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
|
|
1272
1693
|
stream.reset();
|
|
1273
1694
|
}
|
|
1695
|
+
|
|
1274
1696
|
test "|-supereffective|" {
|
|
1275
|
-
try log.supereffective(p1.ident(1));
|
|
1697
|
+
try log.supereffective(.{p1.ident(1)});
|
|
1276
1698
|
try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
|
|
1277
1699
|
stream.reset();
|
|
1278
1700
|
}
|
|
1701
|
+
|
|
1279
1702
|
test "|-resisted|" {
|
|
1280
|
-
try log.resisted(p2.ident(2));
|
|
1703
|
+
try log.resisted(.{p2.ident(2)});
|
|
1281
1704
|
try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
|
|
1282
1705
|
stream.reset();
|
|
1283
1706
|
}
|
|
1707
|
+
|
|
1284
1708
|
test "|-immune|" {
|
|
1285
|
-
try log.immune(p1.ident(3), .None);
|
|
1709
|
+
try log.immune(.{ p1.ident(3), .None });
|
|
1286
1710
|
try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
|
|
1287
1711
|
stream.reset();
|
|
1288
1712
|
|
|
1289
|
-
try log.immune(p2.ident(2), .OHKO);
|
|
1713
|
+
try log.immune(.{ p2.ident(2), .OHKO });
|
|
1290
1714
|
try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
|
|
1291
1715
|
stream.reset();
|
|
1292
1716
|
}
|
|
1717
|
+
|
|
1293
1718
|
test "|-transform|" {
|
|
1294
|
-
try log.transform(p2.ident(4), p1.ident(5));
|
|
1719
|
+
try log.transform(.{ p2.ident(4), p1.ident(5) });
|
|
1295
1720
|
try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
|
|
1296
1721
|
stream.reset();
|
|
1297
1722
|
}
|
|
1723
|
+
|
|
1724
|
+
test "|drag|" {
|
|
1725
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1726
|
+
blissey.level = 91;
|
|
1727
|
+
blissey.hp = 200;
|
|
1728
|
+
blissey.stats.hp = 400;
|
|
1729
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1730
|
+
try log.drag(.{ p2.ident(3), &blissey });
|
|
1731
|
+
const par = 0b1000000;
|
|
1732
|
+
const expected = &(.{
|
|
1733
|
+
N(ArgType.Drag),
|
|
1734
|
+
0b1011,
|
|
1735
|
+
N(S2.Blissey),
|
|
1736
|
+
N(gen2.Gender.Female),
|
|
1737
|
+
91,
|
|
1738
|
+
} ++ switch (endian) {
|
|
1739
|
+
big => .{ 0, 200, 1, 144, par },
|
|
1740
|
+
little => .{ 200, 0, 144, 1, par },
|
|
1741
|
+
});
|
|
1742
|
+
try expectLog2(expected, buf[0..10]);
|
|
1743
|
+
stream.reset();
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
test "|-item|" {
|
|
1747
|
+
try log.item(.{ p2.ident(2), I2.GoldBerry, p1.ident(4) });
|
|
1748
|
+
try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
|
|
1749
|
+
stream.reset();
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
test "|-enditem|" {
|
|
1753
|
+
try log.enditem(.{ p1.ident(1), I2.BerserkGene, .None });
|
|
1754
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
|
|
1755
|
+
stream.reset();
|
|
1756
|
+
|
|
1757
|
+
try log.enditem(.{ p2.ident(4), I2.PRZCureBerry, .Eat });
|
|
1758
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
|
|
1759
|
+
stream.reset();
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
test "|-cureteam|" {
|
|
1763
|
+
try log.cureteam(.{p2.ident(5)});
|
|
1764
|
+
try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
|
|
1765
|
+
stream.reset();
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
test "|-sethp|" {
|
|
1769
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
|
|
1770
|
+
blissey.hp = 612;
|
|
1771
|
+
try log.sethp(.{ p2.ident(2), &blissey, .Silent });
|
|
1772
|
+
const expected: []const u8 = switch (endian) {
|
|
1773
|
+
big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
|
|
1774
|
+
little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
|
|
1775
|
+
};
|
|
1776
|
+
try expectLog2(expected, buf[0..8]);
|
|
1777
|
+
stream.reset();
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
test "|-setboost|" {
|
|
1781
|
+
try log.setboost(.{ p2.ident(6), 6 });
|
|
1782
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
|
|
1783
|
+
stream.reset();
|
|
1784
|
+
|
|
1785
|
+
try log.setboost(.{ p2.ident(3), 2 });
|
|
1786
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
|
|
1787
|
+
stream.reset();
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
test "|-copyboost|" {
|
|
1791
|
+
try log.copyboost(.{ p2.ident(3), p1.ident(6) });
|
|
1792
|
+
try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
|
|
1793
|
+
stream.reset();
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
test "|-sidestart|" {
|
|
1797
|
+
try log.sidestart(.{ .P2, .Reflect });
|
|
1798
|
+
try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
|
|
1799
|
+
stream.reset();
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
test "|-sideend|" {
|
|
1803
|
+
try log.sideend(.{ .P2, .LightScreen });
|
|
1804
|
+
try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
|
|
1805
|
+
stream.reset();
|
|
1806
|
+
|
|
1807
|
+
try log.sideend(.{ .P1, .Spikes, p1.ident(3) });
|
|
1808
|
+
try expectLog2(&.{
|
|
1809
|
+
N(ArgType.SideEnd),
|
|
1810
|
+
0,
|
|
1811
|
+
N(Side.Spikes),
|
|
1812
|
+
0b0011,
|
|
1813
|
+
}, buf[0..4]);
|
|
1814
|
+
stream.reset();
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
test "|-singlemove|" {
|
|
1818
|
+
try log.singlemove(.{ p2.ident(2), M2.DestinyBond });
|
|
1819
|
+
try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
|
|
1820
|
+
stream.reset();
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
test "|-singleturn|" {
|
|
1824
|
+
try log.singleturn(.{ p1.ident(3), M2.Protect });
|
|
1825
|
+
try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
|
|
1826
|
+
stream.reset();
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
test "|-weather|" {
|
|
1830
|
+
try log.weather(.{ W2.Rain, .Upkeep });
|
|
1831
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
|
|
1832
|
+
stream.reset();
|
|
1833
|
+
|
|
1834
|
+
try log.weather(.{ W2.None, .None });
|
|
1835
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
|
|
1836
|
+
stream.reset();
|
|
1837
|
+
}
|