@pkmn/engine 0.1.0-dev.c42deb42 → 0.1.0-dev.c4f94762

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.
Files changed (41) hide show
  1. package/README.md +37 -14
  2. package/build/pkg/addon.js.map +1 -1
  3. package/build/pkg/data/layout.json +2 -2
  4. package/build/pkg/data.d.ts +3 -2
  5. package/build/pkg/data.js.map +1 -1
  6. package/build/pkg/gen1.js +2 -2
  7. package/build/pkg/gen1.js.map +1 -1
  8. package/build/pkg/index.d.ts +2 -1
  9. package/build/pkg/index.js.map +1 -1
  10. package/build/pkg/protocol.js +1 -1
  11. package/build/pkg/protocol.js.map +1 -1
  12. package/build/test/display.js.map +1 -1
  13. package/build/tools/debug.js +3 -1
  14. package/build/tools/debug.js.map +1 -1
  15. package/build.zig +38 -21
  16. package/package.json +23 -19
  17. package/src/bin/install-pkmn-engine +14 -14
  18. package/src/lib/binding/node.zig +6 -10
  19. package/src/lib/common/data.zig +4 -4
  20. package/src/lib/common/protocol.zig +388 -364
  21. package/src/lib/common/rational.zig +11 -7
  22. package/src/lib/common/rng.zig +9 -0
  23. package/src/lib/gen1/README.md +28 -28
  24. package/src/lib/gen1/calc.zig +7 -7
  25. package/src/lib/gen1/chance.zig +4 -4
  26. package/src/lib/gen1/data/moves.zig +10 -10
  27. package/src/lib/gen1/data/species.zig +2 -2
  28. package/src/lib/gen1/data/types.zig +5 -5
  29. package/src/lib/gen1/data.zig +20 -20
  30. package/src/lib/gen1/helpers.zig +13 -13
  31. package/src/lib/gen1/mechanics.zig +267 -281
  32. package/src/lib/gen2/README.md +1 -2
  33. package/src/lib/gen2/calc.zig +143 -0
  34. package/src/lib/gen2/chance.zig +1314 -0
  35. package/src/lib/gen2/data/items.zig +3 -3
  36. package/src/lib/gen2/data/moves.zig +5 -5
  37. package/src/lib/gen2/data/species.zig +1 -1
  38. package/src/lib/gen2/data/types.zig +12 -11
  39. package/src/lib/gen2/data.zig +21 -31
  40. package/src/lib/gen2/generated.zig +806 -0
  41. package/src/lib/gen2/mechanics.zig +1755 -844
@@ -1,6 +1,8 @@
1
1
  const std = @import("std");
2
2
  const builtin = @import("builtin");
3
3
 
4
+ const pkmn = @import("../pkmn.zig");
5
+
4
6
  const data = @import("./data.zig");
5
7
  const options = @import("./options.zig");
6
8
 
@@ -12,6 +14,8 @@ const enabled = options.log;
12
14
  const Player = data.Player;
13
15
  const ID = data.ID;
14
16
 
17
+ const endian = builtin.cpu.arch.endian();
18
+
15
19
  pub const ArgType = enum(u8) {
16
20
  None,
17
21
 
@@ -69,7 +73,7 @@ pub const ArgType = enum(u8) {
69
73
  EndAbility,
70
74
  ClearNegativeBoost,
71
75
  FormeChange,
72
- NoTarget,
76
+ LastNoTarget, // FIXME
73
77
 
74
78
  // Gen 4
75
79
  SwapBoost,
@@ -102,6 +106,7 @@ pub const ArgType = enum(u8) {
102
106
  // Gen 8
103
107
  CanDynamax,
104
108
  SwapSideConditions,
109
+ UpdatePoke,
105
110
 
106
111
  // Gen 9
107
112
  Terastallize,
@@ -150,6 +155,10 @@ pub const Damage = enum(u8) {
150
155
  Clamp,
151
156
  Whirlpool,
152
157
  Spikes,
158
+
159
+ Nightmare,
160
+ Curse,
161
+ Sandstorm,
153
162
  };
154
163
 
155
164
  pub const Status = enum(u8) {
@@ -192,9 +201,11 @@ pub const Activate = enum(u8) {
192
201
  Haze,
193
202
  Mist,
194
203
  Struggle,
195
- Substitute,
204
+ Substitute, // FIXME SubstituteDamage
196
205
  Splash,
197
206
 
207
+ Rage, // TODO
208
+
198
209
  Attract,
199
210
  LockOn,
200
211
  Bind,
@@ -202,8 +213,13 @@ pub const Activate = enum(u8) {
202
213
  FireSpin,
203
214
  Clamp,
204
215
  Whirlpool,
216
+ SubstituteBlock,
217
+
218
+ DestinyBond,
205
219
 
206
220
  BeatUp, // FIXME of
221
+
222
+ Magnitude,
207
223
  };
208
224
 
209
225
  pub const Start = enum(u8) {
@@ -248,6 +264,7 @@ pub const End = enum(u8) {
248
264
  Encore,
249
265
  FutureSight,
250
266
  LeechSeed,
267
+
251
268
  Bind,
252
269
  Wrap,
253
270
  FireSpin,
@@ -263,6 +280,8 @@ pub const End = enum(u8) {
263
280
  LightScreenSilent,
264
281
  ReflectSilent,
265
282
  BideSilent,
283
+
284
+ LeechSeedFrom,
266
285
  };
267
286
 
268
287
  pub const Immune = enum(u8) {
@@ -306,506 +325,484 @@ pub fn Log(comptime Writer: type) type {
306
325
 
307
326
  pub const Error = Writer.Error;
308
327
 
309
- pub fn move(self: Self, source: ID, m: anytype, target: ID) Error!void {
310
- if (!enabled) return;
311
-
312
- assert(m != .None);
313
- try self.writer.writeAll(&.{
314
- @intFromEnum(ArgType.Move),
315
- @as(u8, @bitCast(source)),
316
- @intFromEnum(m),
317
- @as(u8, @bitCast(target)),
318
- @intFromEnum(Move.None),
319
- });
320
- }
321
-
322
- pub fn moveFrom(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
328
+ // source: ID, move: <Move>, target: ID, from?: <Move>
329
+ pub fn move(self: Self, args: anytype) Error!void {
323
330
  if (!enabled) return;
324
331
 
325
- assert(m != .None);
332
+ assert(args[1] != .None);
326
333
  try self.writer.writeAll(&.{
327
334
  @intFromEnum(ArgType.Move),
328
- @as(u8, @bitCast(source)),
329
- @intFromEnum(m),
330
- @as(u8, @bitCast(target)),
335
+ @as(u8, @bitCast(args[0])),
336
+ @intFromEnum(args[1]),
337
+ @as(u8, @bitCast(args[2])),
331
338
  });
332
- try self.writer.writeAll(if (@intFromEnum(from) == 0)
339
+ try self.writer.writeAll(if (args.len < 4 or @intFromEnum(args[3]) == 0)
333
340
  &.{@intFromEnum(Move.None)}
334
341
  else
335
- &.{ @intFromEnum(Move.From), @intFromEnum(from) });
342
+ &.{ @intFromEnum(Move.From), @intFromEnum(args[3]) });
336
343
  }
337
344
 
338
- pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void {
339
- return switchDrag(self, .Switch, ident, pokemon);
345
+ // ident: ID, pokemon: <Pokemon>
346
+ pub fn switched(self: Self, args: anytype) Error!void {
347
+ return switchDrag(self, .Switch, args);
340
348
  }
341
349
 
342
- fn switchDrag(self: Self, arg: ArgType, ident: ID, pokemon: anytype) Error!void {
350
+ // ident: ID, pokemon: <Pokemon>
351
+ fn switchDrag(self: Self, arg: ArgType, args: anytype) Error!void {
343
352
  if (!enabled) return;
344
353
 
345
- try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(ident)) });
346
- if (@hasField(@TypeOf(pokemon.*), "dvs")) {
354
+ try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(args[0])) });
355
+ if (@hasField(@TypeOf(args[1].*), "dvs")) {
347
356
  try self.writer.writeAll(&.{
348
- @intFromEnum(pokemon.species),
349
- @intFromEnum(pokemon.dvs.gender),
350
- pokemon.level,
357
+ @intFromEnum(args[1].species),
358
+ @intFromEnum(args[1].dvs.gender),
359
+ args[1].level,
351
360
  });
352
361
  } else {
353
- try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level });
362
+ try self.writer.writeAll(&.{ @intFromEnum(args[1].species), args[1].level });
354
363
  }
355
- try self.writer.writeIntNative(u16, pokemon.hp);
356
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
357
- try self.writer.writeAll(&.{pokemon.status});
358
- }
359
-
360
- pub fn cant(self: Self, ident: ID, reason: Cant) Error!void {
361
- if (!enabled) return;
362
-
363
- assert(reason != .Disable);
364
- try self.writer.writeAll(&.{
365
- @intFromEnum(ArgType.Cant),
366
- @as(u8, @bitCast(ident)),
367
- @intFromEnum(reason),
368
- });
364
+ try self.writer.writeInt(u16, args[1].hp, endian);
365
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
366
+ try self.writer.writeAll(&.{args[1].status});
369
367
  }
370
368
 
371
- pub fn disabled(self: Self, ident: ID, m: anytype) Error!void {
369
+ // ident: ID, reason: Cant
370
+ // ident: ID, reason: .Disable, move: <Move>
371
+ pub fn cant(self: Self, args: anytype) Error!void {
372
372
  if (!enabled) return;
373
373
 
374
+ assert(args[1] != .Disable or args.len == 3);
374
375
  try self.writer.writeAll(&.{
375
376
  @intFromEnum(ArgType.Cant),
376
- @as(u8, @bitCast(ident)),
377
- @intFromEnum(Cant.Disable),
378
- @intFromEnum(m),
377
+ @as(u8, @bitCast(args[0])),
378
+ @intFromEnum(@as(Cant, args[1])),
379
379
  });
380
+ if (args.len == 3) try self.writer.writeByte(@intFromEnum(args[2]));
380
381
  }
381
382
 
382
- pub fn faint(self: Self, ident: ID, done: bool) Error!void {
383
+ // ident: ID, done: bool
384
+ pub fn faint(self: Self, args: anytype) Error!void {
383
385
  if (!enabled) return;
384
386
 
385
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) });
386
- if (done) try self.writer.writeByte(@intFromEnum(ArgType.None));
387
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(args[0])) });
388
+ if (args[1]) try self.writer.writeByte(@intFromEnum(ArgType.None));
387
389
  }
388
390
 
389
- pub fn turn(self: Self, num: u16) Error!void {
391
+ // num: u16
392
+ pub fn turn(self: Self, args: anytype) Error!void {
390
393
  if (!enabled) return;
391
394
 
392
395
  try self.writer.writeByte(@intFromEnum(ArgType.Turn));
393
- try self.writer.writeIntNative(u16, num);
396
+ try self.writer.writeInt(u16, args[0], endian);
394
397
  try self.writer.writeByte(@intFromEnum(ArgType.None));
395
398
  }
396
399
 
397
- pub fn win(self: Self, player: Player) Error!void {
400
+ // player: Player
401
+ pub fn win(self: Self, args: anytype) Error!void {
398
402
  if (!enabled) return;
399
403
 
400
404
  try self.writer.writeAll(&.{
401
405
  @intFromEnum(ArgType.Win),
402
- @intFromEnum(player),
406
+ @intFromEnum(@as(Player, args[0])),
403
407
  @intFromEnum(ArgType.None),
404
408
  });
405
409
  }
406
410
 
407
- pub fn tie(self: Self) Error!void {
411
+ // -
412
+ pub fn tie(self: Self, _: anytype) Error!void {
408
413
  if (!enabled) return;
409
414
 
410
415
  try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
411
416
  }
412
417
 
413
- pub fn damage(self: Self, ident: ID, pokemon: anytype, reason: Damage) Error!void {
414
- if (!enabled) return;
415
-
416
- assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed));
417
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
418
- try self.writer.writeIntNative(u16, pokemon.hp);
419
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
420
- try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
421
- }
422
-
423
- pub fn damageOf(
424
- self: Self,
425
- ident: ID,
426
- pokemon: anytype,
427
- reason: Damage,
428
- source: ID,
429
- ) Error!void {
430
- if (!enabled) return;
431
-
432
- assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf));
433
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
434
- try self.writer.writeIntNative(u16, pokemon.hp);
435
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
436
- try self.writer.writeAll(&.{
437
- pokemon.status,
438
- @intFromEnum(reason),
439
- @as(u8, @bitCast(source)),
440
- });
441
- }
442
-
443
- pub fn heal(self: Self, ident: ID, pokemon: anytype, reason: Heal) Error!void {
444
- if (!enabled) return;
445
-
446
- assert(reason != .Drain);
447
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(ident)) });
448
- try self.writer.writeIntNative(u16, pokemon.hp);
449
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
450
- try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
451
- }
452
-
453
- pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
418
+ // ident: ID, pokemon: <Pokemon>, reason: Damage
419
+ // ident: ID, pokemon: <Pokemon>, reason: .RecoilOf, source: ID
420
+ pub fn damage(self: Self, args: anytype) Error!void {
454
421
  if (!enabled) return;
455
422
 
456
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
457
- try self.writer.writeIntNative(u16, pokemon.hp);
458
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
423
+ assert(args[2] != .RecoilOf or args.len == 4);
459
424
  try self.writer.writeAll(&.{
460
- pokemon.status,
461
- @intFromEnum(Heal.Drain),
462
- @as(u8, @bitCast(target)),
425
+ @intFromEnum(ArgType.Damage),
426
+ @as(u8, @bitCast(args[0])),
463
427
  });
428
+ try self.writer.writeInt(u16, args[1].hp, endian);
429
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
430
+ try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Damage, args[2])) });
431
+ if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
464
432
  }
465
433
 
466
- pub fn status(self: Self, ident: ID, value: u8, reason: Status) Error!void {
434
+ // ident: ID, pokemon: <Pokemon>, reason: Heal
435
+ // ident: ID, pokemon: <Pokemon>, reason: .Drain, target: ID
436
+ pub fn heal(self: Self, args: anytype) Error!void {
467
437
  if (!enabled) return;
468
438
 
469
- assert(reason != .From);
470
- try self.writer.writeAll(&.{
471
- @intFromEnum(ArgType.Status),
472
- @as(u8, @bitCast(ident)),
473
- value,
474
- @intFromEnum(reason),
475
- });
439
+ assert(args[2] != .Drain or args.len == 4);
440
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
441
+ try self.writer.writeInt(u16, args[1].hp, endian);
442
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
443
+ try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Heal, args[2])) });
444
+ if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
476
445
  }
477
446
 
478
- pub fn statusFrom(self: Self, ident: ID, value: u8, m: anytype) Error!void {
447
+ // ident: ID, value: u8, reason: Status
448
+ // ident: ID, value: u8, reason: .From, m: <Move>
449
+ pub fn status(self: Self, args: anytype) Error!void {
479
450
  if (!enabled) return;
480
451
 
452
+ assert(args[2] != .From or args.len == 4);
481
453
  try self.writer.writeAll(&.{
482
454
  @intFromEnum(ArgType.Status),
483
- @as(u8, @bitCast(ident)),
484
- value,
485
- @intFromEnum(Status.From),
486
- @intFromEnum(m),
455
+ @as(u8, @bitCast(args[0])),
456
+ args[1],
457
+ @intFromEnum(@as(Status, args[2])),
487
458
  });
459
+ if (args.len == 4) try self.writer.writeByte(@intFromEnum(args[3]));
488
460
  }
489
461
 
490
- pub fn curestatus(self: Self, ident: ID, value: u8, reason: CureStatus) Error!void {
462
+ // ident: ID, value: u8, reason: CureStatus
463
+ pub fn curestatus(self: Self, args: anytype) Error!void {
491
464
  if (!enabled) return;
492
465
 
493
466
  try self.writer.writeAll(&.{
494
467
  @intFromEnum(ArgType.CureStatus),
495
- @as(u8, @bitCast(ident)),
496
- value,
497
- @intFromEnum(reason),
468
+ @as(u8, @bitCast(args[0])),
469
+ args[1],
470
+ @intFromEnum(@as(CureStatus, args[2])),
498
471
  });
499
472
  }
500
473
 
501
- pub fn boost(self: Self, ident: ID, reason: Boost, num: i8) Error!void {
474
+ // ident: ID, reason: Boost, num: i8
475
+ pub fn boost(self: Self, args: anytype) Error!void {
502
476
  if (!enabled) return;
503
477
 
504
- assert(num != 0 and (reason != .Rage or num > 0));
478
+ assert(args[2] != 0 and (args[1] != .Rage or args[2] > 0));
505
479
  try self.writer.writeAll(&.{
506
480
  @intFromEnum(ArgType.Boost),
507
- @as(u8, @bitCast(ident)),
508
- @intFromEnum(reason),
509
- @as(u8, @intCast(num + 6)),
481
+ @as(u8, @bitCast(args[0])),
482
+ @intFromEnum(@as(Boost, args[1])),
483
+ @as(u8, @intCast(@as(i8, args[2]) + 6)),
510
484
  });
511
485
  }
512
486
 
513
- pub fn clearallboost(self: Self) Error!void {
487
+ // -
488
+ pub fn clearallboost(self: Self, _: anytype) Error!void {
514
489
  if (!enabled) return;
515
490
 
516
491
  try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
517
492
  }
518
493
 
519
- pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
494
+ // ident: ID, reason: Fail
495
+ pub fn fail(self: Self, args: anytype) Error!void {
520
496
  if (!enabled) return;
521
497
 
522
498
  try self.writer.writeAll(&.{
523
499
  @intFromEnum(ArgType.Fail),
524
- @as(u8, @bitCast(ident)),
525
- @intFromEnum(reason),
500
+ @as(u8, @bitCast(args[0])),
501
+ @intFromEnum(@as(Fail, args[1])),
526
502
  });
527
503
  }
528
504
 
529
- pub fn miss(self: Self, source: ID) Error!void {
505
+ // source: ID
506
+ pub fn miss(self: Self, args: anytype) Error!void {
530
507
  if (!enabled) return;
531
508
 
532
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) });
509
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(args[0])) });
533
510
  }
534
511
 
535
- pub fn hitcount(self: Self, ident: ID, num: u8) Error!void {
512
+ // ident: ID, num: u8
513
+ pub fn hitcount(self: Self, args: anytype) Error!void {
536
514
  if (!enabled) return;
537
515
 
538
516
  try self.writer.writeAll(&.{
539
517
  @intFromEnum(ArgType.HitCount),
540
- @as(u8, @bitCast(ident)),
541
- num,
518
+ @as(u8, @bitCast(args[0])),
519
+ args[1],
542
520
  });
543
521
  }
544
522
 
545
- pub fn prepare(self: Self, source: ID, m: anytype) Error!void {
523
+ // source: ID, m: <Move>
524
+ pub fn prepare(self: Self, args: anytype) Error!void {
546
525
  if (!enabled) return;
547
526
 
548
527
  try self.writer.writeAll(&.{
549
528
  @intFromEnum(ArgType.Prepare),
550
- @as(u8, @bitCast(source)),
551
- @intFromEnum(m),
529
+ @as(u8, @bitCast(args[0])),
530
+ @intFromEnum(args[1]),
552
531
  });
553
532
  }
554
533
 
555
- pub fn mustrecharge(self: Self, ident: ID) Error!void {
534
+ // ident: ID
535
+ pub fn mustrecharge(self: Self, args: anytype) Error!void {
556
536
  if (!enabled) return;
557
537
 
558
538
  try self.writer.writeAll(&.{
559
539
  @intFromEnum(ArgType.MustRecharge),
560
- @as(u8, @bitCast(ident)),
540
+ @as(u8, @bitCast(args[0])),
561
541
  });
562
542
  }
563
543
 
564
- pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
544
+ // ident: ID, reason: Activate
545
+ // ident: ID, reason: .SubstituteBlock, m: <Move>
546
+ // ident: ID, reason: .Magnitude, num: u8
547
+ pub fn activate(self: Self, args: anytype) Error!void {
565
548
  if (!enabled) return;
566
549
 
550
+ assert(args.len <= 4);
551
+ const reason: Activate = args[1];
567
552
  try self.writer.writeAll(&.{
568
553
  @intFromEnum(ArgType.Activate),
569
- @as(u8, @bitCast(ident)),
554
+ @as(u8, @bitCast(args[0])),
570
555
  @intFromEnum(reason),
571
556
  });
557
+ if (args.len == 3) {
558
+ if (reason == .SubstituteBlock) {
559
+ try self.writer.writeByte(@intFromEnum(args[2]));
560
+ } else {
561
+ assert(reason == .Magnitude);
562
+ try self.writer.writeByte(args[2]);
563
+ }
564
+ }
572
565
  }
573
566
 
574
- pub fn fieldactivate(self: Self) Error!void {
567
+ // -
568
+ pub fn fieldactivate(self: Self, _: anytype) Error!void {
575
569
  if (!enabled) return;
576
570
 
577
571
  try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
578
572
  }
579
573
 
580
- pub fn start(self: Self, ident: ID, reason: Start) Error!void {
581
- if (!enabled) return;
582
-
583
- assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
584
- try self.writer.writeAll(&.{
585
- @intFromEnum(ArgType.Start),
586
- @as(u8, @bitCast(ident)),
587
- @intFromEnum(reason),
588
- });
589
- }
590
-
591
- pub fn typechange(self: Self, source: ID, types: anytype, target: ID) Error!void {
592
- if (!enabled) return;
593
-
594
- try self.writer.writeAll(&.{
595
- @intFromEnum(ArgType.Start),
596
- @as(u8, @bitCast(source)),
597
- @intFromEnum(Start.TypeChange),
598
- @as(u8, @bitCast(types)),
599
- @as(u8, @bitCast(target)),
600
- });
601
- }
602
-
603
- pub fn startEffect(self: Self, ident: ID, reason: Start, m: anytype) Error!void {
574
+ // ident: ID, reason: Start
575
+ // ident: ID, reason: .Disable | .Mimic | .Encore, m: <Move>
576
+ // ident: ID, reason: .TypeChange, types: <Types>, target: ID
577
+ pub fn start(self: Self, args: anytype) Error!void {
604
578
  if (!enabled) return;
605
579
 
606
- assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
580
+ assert(args.len <= 4);
581
+ const reason: Start = args[1];
607
582
  try self.writer.writeAll(&.{
608
583
  @intFromEnum(ArgType.Start),
609
- @as(u8, @bitCast(ident)),
584
+ @as(u8, @bitCast(args[0])),
610
585
  @intFromEnum(reason),
611
- @intFromEnum(m),
612
586
  });
587
+ if (args.len == 3) {
588
+ assert(reason == .Disable or reason == .Mimic or reason == .Encore);
589
+ try self.writer.writeByte(@intFromEnum(args[2]));
590
+ } else if (args.len == 4) {
591
+ assert(reason == .TypeChange);
592
+ // FIXME: u16 types in Generation II
593
+ try self.writer.writeAll(&.{
594
+ @as(u8, @bitCast(args[2])),
595
+ @as(u8, @bitCast(args[3])),
596
+ });
597
+ }
613
598
  }
614
599
 
615
- pub fn end(self: Self, ident: ID, reason: End) Error!void {
600
+ // ident: ID, reason: End
601
+ pub fn end(self: Self, args: anytype) Error!void {
616
602
  if (!enabled) return;
617
603
 
618
604
  try self.writer.writeAll(&.{
619
605
  @intFromEnum(ArgType.End),
620
- @as(u8, @bitCast(ident)),
621
- @intFromEnum(reason),
606
+ @as(u8, @bitCast(args[0])),
607
+ @intFromEnum(@as(End, args[1])),
622
608
  });
623
609
  }
624
610
 
625
- pub fn ohko(self: Self) Error!void {
611
+ // -
612
+ pub fn ohko(self: Self, _: anytype) Error!void {
626
613
  if (!enabled) return;
627
614
 
628
615
  try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
629
616
  }
630
617
 
631
- pub fn crit(self: Self, ident: ID) Error!void {
618
+ // ident: ID
619
+ pub fn crit(self: Self, args: anytype) Error!void {
632
620
  if (!enabled) return;
633
621
 
634
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) });
622
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(args[0])) });
635
623
  }
636
624
 
637
- pub fn supereffective(self: Self, ident: ID) Error!void {
625
+ // ident: ID
626
+ pub fn supereffective(self: Self, args: anytype) Error!void {
638
627
  if (!enabled) return;
639
628
 
640
629
  try self.writer.writeAll(&.{
641
630
  @intFromEnum(ArgType.SuperEffective),
642
- @as(u8, @bitCast(ident)),
631
+ @as(u8, @bitCast(args[0])),
643
632
  });
644
633
  }
645
634
 
646
- pub fn resisted(self: Self, ident: ID) Error!void {
635
+ // ident: ID
636
+ pub fn resisted(self: Self, args: anytype) Error!void {
647
637
  if (!enabled) return;
648
638
 
649
639
  try self.writer.writeAll(&.{
650
640
  @intFromEnum(ArgType.Resisted),
651
- @as(u8, @bitCast(ident)),
641
+ @as(u8, @bitCast(args[0])),
652
642
  });
653
643
  }
654
644
 
655
- pub fn immune(self: Self, ident: ID, reason: Immune) Error!void {
645
+ // ident: ID, reason: Immune
646
+ pub fn immune(self: Self, args: anytype) Error!void {
656
647
  if (!enabled) return;
657
648
 
658
649
  try self.writer.writeAll(&.{
659
650
  @intFromEnum(ArgType.Immune),
660
- @as(u8, @bitCast(ident)),
661
- @intFromEnum(reason),
651
+ @as(u8, @bitCast(args[0])),
652
+ @intFromEnum(@as(Immune, args[1])),
662
653
  });
663
654
  }
664
655
 
665
- pub fn transform(self: Self, source: ID, target: ID) Error!void {
656
+ // source: ID, target: ID
657
+ pub fn transform(self: Self, args: anytype) Error!void {
666
658
  if (!enabled) return;
667
659
 
668
660
  try self.writer.writeAll(&.{
669
661
  @intFromEnum(ArgType.Transform),
670
- @as(u8, @bitCast(source)),
671
- @as(u8, @bitCast(target)),
662
+ @as(u8, @bitCast(args[0])),
663
+ @as(u8, @bitCast(args[1])),
672
664
  });
673
665
  }
674
666
 
675
- pub fn drag(self: Self, ident: ID, pokemon: anytype) Error!void {
676
- return switchDrag(self, .Drag, ident, pokemon);
667
+ // ident: ID, pokemon: <Pokemon>
668
+ pub fn drag(self: Self, args: anytype) Error!void {
669
+ return switchDrag(self, .Drag, args);
677
670
  }
678
671
 
679
- pub fn item(self: Self, target: ID, i: anytype, source: ID) Error!void {
672
+ // target: ID, item: <Item>, source: ID
673
+ pub fn item(self: Self, args: anytype) Error!void {
680
674
  if (!enabled) return;
681
675
 
682
676
  try self.writer.writeAll(&.{
683
677
  @intFromEnum(ArgType.Item),
684
- @as(u8, @bitCast(target)),
685
- @intFromEnum(i),
686
- @as(u8, @bitCast(source)),
678
+ @as(u8, @bitCast(args[0])),
679
+ @intFromEnum(args[1]),
680
+ @as(u8, @bitCast(args[2])),
687
681
  });
688
682
  }
689
683
 
690
- pub fn enditem(self: Self, ident: ID, i: anytype, reason: EndItem) Error!void {
684
+ // ident: ID, item: <Item>, reason: EndItem
685
+ pub fn enditem(self: Self, args: anytype) Error!void {
691
686
  if (!enabled) return;
692
687
 
693
688
  try self.writer.writeAll(&.{
694
689
  @intFromEnum(ArgType.EndItem),
695
- @as(u8, @bitCast(ident)),
696
- @intFromEnum(i),
697
- @intFromEnum(reason),
690
+ @as(u8, @bitCast(args[0])),
691
+ @intFromEnum(args[1]),
692
+ @intFromEnum(@as(EndItem, args[2])),
698
693
  });
699
694
  }
700
695
 
701
- pub fn cureteam(self: Self, source: ID) Error!void {
696
+ // source: ID
697
+ pub fn cureteam(self: Self, args: anytype) Error!void {
702
698
  if (!enabled) return;
703
699
 
704
700
  try self.writer.writeAll(&.{
705
701
  @intFromEnum(ArgType.CureTeam),
706
- @as(u8, @bitCast(source)),
702
+ @as(u8, @bitCast(args[0])),
707
703
  });
708
704
  }
709
705
 
710
- pub fn sethp(self: Self, ident: ID, pokemon: anytype, reason: SetHP) Error!void {
706
+ // ident: ID, pokemon: <Pokemon>, reason: SetHP
707
+ pub fn sethp(self: Self, args: anytype) Error!void {
711
708
  if (!enabled) return;
712
709
 
713
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(ident)) });
714
- try self.writer.writeIntNative(u16, pokemon.hp);
715
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
716
- try self.writer.writeAll(&.{pokemon.status});
717
- try self.writer.writeByte(@intFromEnum(reason));
710
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(args[0])) });
711
+ try self.writer.writeInt(u16, args[1].hp, endian);
712
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
713
+ try self.writer.writeAll(&.{args[1].status});
714
+ try self.writer.writeByte(@intFromEnum(@as(SetHP, args[2])));
718
715
  }
719
716
 
720
- pub fn setboost(self: Self, ident: ID, num: i8) Error!void {
717
+ // ident: ID, num: i8
718
+ pub fn setboost(self: Self, args: anytype) Error!void {
721
719
  if (!enabled) return;
722
720
 
723
721
  try self.writer.writeAll(&.{
724
722
  @intFromEnum(ArgType.SetBoost),
725
- @as(u8, @bitCast(ident)),
726
- @as(u8, @intCast(num + 6)),
723
+ @as(u8, @bitCast(args[0])),
724
+ @as(u8, @intCast(args[1] + 6)),
727
725
  });
728
726
  }
729
727
 
730
- pub fn copyboost(self: Self, source: ID, target: ID) Error!void {
728
+ // source: ID, target: ID
729
+ pub fn copyboost(self: Self, args: anytype) Error!void {
731
730
  if (!enabled) return;
732
731
 
733
732
  try self.writer.writeAll(&.{
734
733
  @intFromEnum(ArgType.CopyBoost),
735
- @as(u8, @bitCast(source)),
736
- @as(u8, @bitCast(target)),
734
+ @as(u8, @bitCast(args[0])),
735
+ @as(u8, @bitCast(args[1])),
737
736
  });
738
737
  }
739
738
 
740
- pub fn sidestart(self: Self, player: Player, reason: Side) Error!void {
739
+ // player: Player, reason: Side
740
+ pub fn sidestart(self: Self, args: anytype) Error!void {
741
741
  if (!enabled) return;
742
742
 
743
743
  try self.writer.writeAll(&.{
744
744
  @intFromEnum(ArgType.SideStart),
745
- @intFromEnum(player),
746
- @intFromEnum(reason),
747
- });
748
- }
749
-
750
- pub fn sideend(self: Self, player: Player, reason: Side) Error!void {
751
- if (!enabled) return;
752
-
753
- assert(@intFromEnum(reason) != @intFromEnum(Side.Spikes));
754
- try self.writer.writeAll(&.{
755
- @intFromEnum(ArgType.SideEnd),
756
- @intFromEnum(player),
757
- @intFromEnum(reason),
745
+ @intFromEnum(@as(Player, args[0])),
746
+ @intFromEnum(@as(Side, args[1])),
758
747
  });
759
748
  }
760
749
 
761
- pub fn spikesend(self: Self, player: Player, m: anytype, source: ID) Error!void {
750
+ // player: Player, reason: Side
751
+ // player: Player, reason: .Spikes, source: ID
752
+ pub fn sideend(self: Self, args: anytype) Error!void {
762
753
  if (!enabled) return;
763
754
 
755
+ assert(args[1] != .Spikes or args.len == 3);
764
756
  try self.writer.writeAll(&.{
765
757
  @intFromEnum(ArgType.SideEnd),
766
- @intFromEnum(player),
767
- @intFromEnum(Side.Spikes),
768
- @intFromEnum(m),
769
- @as(u8, @bitCast(source)),
758
+ @intFromEnum(@as(Player, args[0])),
759
+ @intFromEnum(@as(Side, args[1])),
770
760
  });
761
+ if (args.len == 3) try self.writer.writeByte(@as(u8, @bitCast(args[2])));
771
762
  }
772
763
 
773
- pub fn singlemove(self: Self, ident: ID, m: anytype) Error!void {
774
- return single(self, .SingleMove, ident, m);
764
+ // ident: ID, move: <Move>
765
+ pub fn singlemove(self: Self, args: anytype) Error!void {
766
+ return single(self, .SingleMove, args);
775
767
  }
776
768
 
777
- pub fn singleturn(self: Self, ident: ID, m: anytype) Error!void {
778
- return single(self, .SingleTurn, ident, m);
769
+ // ident: ID, move: <Move>
770
+ pub fn singleturn(self: Self, args: anytype) Error!void {
771
+ return single(self, .SingleTurn, args);
779
772
  }
780
773
 
781
- fn single(self: Self, arg: ArgType, ident: ID, m: anytype) Error!void {
774
+ // ident: ID, move: <Move>
775
+ fn single(self: Self, arg: ArgType, args: anytype) Error!void {
782
776
  if (!enabled) return;
783
777
 
784
778
  try self.writer.writeAll(&.{
785
779
  @intFromEnum(arg),
786
- @as(u8, @bitCast(ident)),
787
- @intFromEnum(m),
780
+ @as(u8, @bitCast(args[0])),
781
+ @intFromEnum(args[1]),
788
782
  });
789
783
  }
790
784
 
791
- pub fn weather(self: Self, w: anytype, reason: Weather) Error!void {
785
+ // weather: <Weather>, reason: Weather
786
+ pub fn weather(self: Self, args: anytype) Error!void {
792
787
  if (!enabled) return;
793
788
 
794
- assert(!(w == .None and reason == .Upkeep));
789
+ assert(!(args[0] == .None and args[1] == .Upkeep));
795
790
  try self.writer.writeAll(&.{
796
791
  @intFromEnum(ArgType.Weather),
797
- @intFromEnum(w),
798
- @intFromEnum(reason),
792
+ @intFromEnum(args[0]),
793
+ @intFromEnum(@as(Weather, args[1])),
799
794
  });
800
795
  }
801
796
 
802
- pub fn laststill(self: Self) Error!void {
797
+ // -
798
+ pub fn laststill(self: Self, _: anytype) Error!void {
803
799
  if (!enabled) return;
804
800
 
805
801
  try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
806
802
  }
807
803
 
808
- pub fn lastmiss(self: Self) Error!void {
804
+ // -
805
+ pub fn lastmiss(self: Self, _: anytype) Error!void {
809
806
  if (!enabled) return;
810
807
 
811
808
  try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
@@ -836,10 +833,10 @@ pub const ByteStream = struct {
836
833
  try self.stream.writeByte(byte);
837
834
  }
838
835
 
839
- pub fn writeIntNative(self: Writer, comptime T: type, value: T) Error!void {
836
+ pub fn writeInt(self: Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
840
837
  // TODO: rework this to write directly to the buffer?
841
- var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
842
- std.mem.writeIntNative(T, &bytes, value);
838
+ var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined;
839
+ std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(v)), &bytes, v, end);
843
840
  return self.writeAll(&bytes);
844
841
  }
845
842
  };
@@ -948,19 +945,19 @@ pub fn format(
948
945
  if (a[i] == N(gen.Gender.Unknown)) {
949
946
  i += 1;
950
947
  } else {
951
- var gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
948
+ const gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
952
949
  printc(", {s}", .{gender}, a, b, &i, 1, color);
953
950
  }
954
951
  }
955
952
  printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
956
953
  switch (endian) {
957
- .Big => {
954
+ .big => {
958
955
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
959
956
  printc(" {d}", .{hp}, a, b, &i, 2, color);
960
957
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
961
958
  printc("/{d}", .{hp}, a, b, &i, 2, color);
962
959
  },
963
- .Little => {
960
+ .little => {
964
961
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
965
962
  printc(" {d}", .{hp}, a, b, &i, 2, color);
966
963
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -991,8 +988,8 @@ pub fn format(
991
988
  },
992
989
  .Turn => {
993
990
  const turn = switch (endian) {
994
- .Big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
995
- .Little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
991
+ .big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
992
+ .little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
996
993
  };
997
994
  printc(" {d}", .{turn}, a, b, &i, 2, color);
998
995
  },
@@ -1003,13 +1000,13 @@ pub fn format(
1003
1000
  var id = ID.from(@intCast(a[i]));
1004
1001
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1005
1002
  switch (endian) {
1006
- .Big => {
1003
+ .big => {
1007
1004
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1008
1005
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1009
1006
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1010
1007
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1011
1008
  },
1012
- .Little => {
1009
+ .little => {
1013
1010
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1014
1011
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1015
1012
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1074,7 +1071,13 @@ pub fn format(
1074
1071
  .Activate => {
1075
1072
  const id = ID.from(@intCast(a[i]));
1076
1073
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1077
- printc(" {s}", .{@tagName(@as(Activate, @enumFromInt(a[i])))}, a, b, &i, 1, color);
1074
+ const reason: Activate = @enumFromInt(a[i]);
1075
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
1076
+ if (reason == .SubstituteBlock) {
1077
+ printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
1078
+ } else if (reason == .Magnitude) {
1079
+ printc(" {d}", .{a[i]}, a, b, &i, 1, color);
1080
+ }
1078
1081
  },
1079
1082
  .Start => {
1080
1083
  const id = ID.from(@intCast(a[i]));
@@ -1082,6 +1085,7 @@ pub fn format(
1082
1085
  const reason = a[i];
1083
1086
  printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
1084
1087
  if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
1088
+ // FIXME
1085
1089
  const types = @as(gen1.Types, @bitCast(a[i]));
1086
1090
  const args = .{
1087
1091
  formatter(gen, .Type, @intFromEnum(types.type1)),
@@ -1124,13 +1128,13 @@ pub fn format(
1124
1128
  const id = ID.from(@intCast(a[i]));
1125
1129
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1126
1130
  switch (endian) {
1127
- .Big => {
1131
+ .big => {
1128
1132
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1129
1133
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1130
1134
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1131
1135
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1132
1136
  },
1133
- .Little => {
1137
+ .little => {
1134
1138
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1135
1139
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1136
1140
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1237,8 +1241,6 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
1237
1241
  }
1238
1242
  }
1239
1243
 
1240
- const endian = builtin.target.cpu.arch.endian();
1241
-
1242
1244
  fn N(e: anytype) u8 {
1243
1245
  return @intFromEnum(e);
1244
1246
  }
@@ -1256,7 +1258,7 @@ const gen2 = struct {
1256
1258
  pub const helpers = @import("../gen2/helpers.zig");
1257
1259
  };
1258
1260
 
1259
- var buf: [gen1.LOGS_SIZE]u8 = undefined;
1261
+ var buf: [pkmn.LOGS_SIZE]u8 = undefined;
1260
1262
  var stream: ByteStream = .{ .buffer = &buf };
1261
1263
  var log: FixedLog = .{ .writer = stream.writer() };
1262
1264
 
@@ -1294,22 +1296,22 @@ fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
1294
1296
  }
1295
1297
 
1296
1298
  test "|move|" {
1297
- try log.move(p2.ident(4), M1.Thunderbolt, p1.ident(5));
1299
+ try log.move(.{ p2.ident(4), M1.Thunderbolt, p1.ident(5) });
1298
1300
  try expectLog1(
1299
1301
  &.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
1300
1302
  buf[0..5],
1301
1303
  );
1302
1304
  stream.reset();
1303
1305
 
1304
- try log.moveFrom(p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome);
1306
+ try log.move(.{ p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome });
1305
1307
  try expectLog1(
1306
1308
  &.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
1307
1309
  buf[0..6],
1308
1310
  );
1309
1311
  stream.reset();
1310
1312
 
1311
- try log.move(p2.ident(4), M1.SkullBash, .{});
1312
- try log.laststill();
1313
+ try log.move(.{ p2.ident(4), M1.SkullBash, ID{} });
1314
+ try log.laststill(.{});
1313
1315
  try expectLog1(
1314
1316
  &.{
1315
1317
  N(ArgType.Move),
@@ -1323,8 +1325,8 @@ test "|move|" {
1323
1325
  );
1324
1326
  stream.reset();
1325
1327
 
1326
- try log.move(p2.ident(4), M1.Tackle, p1.ident(5));
1327
- try log.lastmiss();
1328
+ try log.move(.{ p2.ident(4), M1.Tackle, p1.ident(5) });
1329
+ try log.lastmiss(.{});
1328
1330
  try expectLog1(
1329
1331
  &.{
1330
1332
  N(ArgType.Move),
@@ -1345,11 +1347,11 @@ test "|switch|" {
1345
1347
  snorlax.hp = 200;
1346
1348
  snorlax.stats.hp = 400;
1347
1349
  snorlax.status = gen1.Status.init(.PAR);
1348
- try log.switched(p2.ident(3), &snorlax);
1350
+ try log.switched(.{ p2.ident(3), &snorlax });
1349
1351
  const par = 0b1000000;
1350
1352
  var expected: []const u8 = switch (endian) {
1351
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1352
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1353
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1354
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1353
1355
  };
1354
1356
  try expectLog1(expected, buf[0..9]);
1355
1357
  stream.reset();
@@ -1357,19 +1359,19 @@ test "|switch|" {
1357
1359
  snorlax.level = 100;
1358
1360
  snorlax.hp = 0;
1359
1361
  snorlax.status = 0;
1360
- try log.switched(p2.ident(3), &snorlax);
1362
+ try log.switched(.{ p2.ident(3), &snorlax });
1361
1363
  expected = switch (endian) {
1362
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1363
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1364
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1365
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1364
1366
  };
1365
1367
  try expectLog1(expected, buf[0..9]);
1366
1368
  stream.reset();
1367
1369
 
1368
1370
  snorlax.hp = 400;
1369
- try log.switched(p2.ident(3), &snorlax);
1371
+ try log.switched(.{ p2.ident(3), &snorlax });
1370
1372
  expected = switch (endian) {
1371
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1372
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1373
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1374
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1373
1375
  };
1374
1376
  try expectLog1(expected, buf[0..9]);
1375
1377
  stream.reset();
@@ -1379,7 +1381,7 @@ test "|switch|" {
1379
1381
  blissey.hp = 200;
1380
1382
  blissey.stats.hp = 400;
1381
1383
  blissey.status = gen2.Status.init(.PAR);
1382
- try log.switched(p2.ident(3), &blissey);
1384
+ try log.switched(.{ p2.ident(3), &blissey });
1383
1385
  expected = &(.{
1384
1386
  N(ArgType.Switch),
1385
1387
  0b1011,
@@ -1387,51 +1389,51 @@ test "|switch|" {
1387
1389
  N(gen2.Gender.Female),
1388
1390
  91,
1389
1391
  } ++ switch (endian) {
1390
- .Big => .{ 0, 200, 1, 144, par },
1391
- .Little => .{ 200, 0, 144, 1, par },
1392
+ .big => .{ 0, 200, 1, 144, par },
1393
+ .little => .{ 200, 0, 144, 1, par },
1392
1394
  });
1393
1395
  try expectLog2(expected, buf[0..10]);
1394
1396
  stream.reset();
1395
1397
  }
1396
1398
 
1397
1399
  test "|cant|" {
1398
- try log.cant(p2.ident(6), .Bound);
1400
+ try log.cant(.{ p2.ident(6), .Bound });
1399
1401
  try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
1400
1402
  stream.reset();
1401
1403
 
1402
- try log.disabled(p1.ident(2), M1.Earthquake);
1404
+ try log.cant(.{ p1.ident(2), .Disable, M1.Earthquake });
1403
1405
  try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
1404
1406
  stream.reset();
1405
1407
  }
1406
1408
 
1407
1409
  test "|faint|" {
1408
- try log.faint(p2.ident(2), false);
1410
+ try log.faint(.{ p2.ident(2), false });
1409
1411
  try expectLog1(&.{ N(ArgType.Faint), 0b1010 }, buf[0..2]);
1410
1412
  stream.reset();
1411
1413
 
1412
- try log.faint(p2.ident(2), true);
1414
+ try log.faint(.{ p2.ident(2), true });
1413
1415
  try expectLog1(&.{ N(ArgType.Faint), 0b1010, N(ArgType.None) }, buf[0..3]);
1414
1416
  stream.reset();
1415
1417
  }
1416
1418
 
1417
1419
  test "|turn|" {
1418
- try log.turn(42);
1419
- var expected = switch (endian) {
1420
- .Big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1421
- .Little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1420
+ try log.turn(.{42});
1421
+ const expected = switch (endian) {
1422
+ .big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1423
+ .little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1422
1424
  };
1423
1425
  try expectLog1(expected, buf[0..4]);
1424
1426
  stream.reset();
1425
1427
  }
1426
1428
 
1427
1429
  test "|win|" {
1428
- try log.win(.P2);
1430
+ try log.win(.{.P2});
1429
1431
  try expectLog1(&.{ N(ArgType.Win), 1, N(ArgType.None) }, buf[0..3]);
1430
1432
  stream.reset();
1431
1433
  }
1432
1434
 
1433
1435
  test "|tie|" {
1434
- try log.tie();
1436
+ try log.tie(.{});
1435
1437
  try expectLog1(&.{ N(ArgType.Tie), N(ArgType.None) }, buf[0..2]);
1436
1438
  stream.reset();
1437
1439
  }
@@ -1440,10 +1442,10 @@ test "|-damage|" {
1440
1442
  var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
1441
1443
  chansey.hp = 612;
1442
1444
  chansey.status = gen1.Status.slp(1);
1443
- try log.damage(p2.ident(2), &chansey, .None);
1445
+ try log.damage(.{ p2.ident(2), &chansey, .None });
1444
1446
  var expected: []const u8 = switch (endian) {
1445
- .Big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1446
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1447
+ .big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1448
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1447
1449
  };
1448
1450
  try expectLog1(expected, buf[0..8]);
1449
1451
  stream.reset();
@@ -1451,19 +1453,19 @@ test "|-damage|" {
1451
1453
  chansey.hp = 100;
1452
1454
  chansey.stats.hp = 256;
1453
1455
  chansey.status = 0;
1454
- try log.damage(p2.ident(2), &chansey, .Confusion);
1456
+ try log.damage(.{ p2.ident(2), &chansey, .Confusion });
1455
1457
  expected = switch (endian) {
1456
- .Big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1457
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1458
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1459
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1458
1460
  };
1459
1461
  try expectLog1(expected, buf[0..8]);
1460
1462
  stream.reset();
1461
1463
 
1462
1464
  chansey.status = gen1.Status.init(.PSN);
1463
- try log.damageOf(p2.ident(2), &chansey, .RecoilOf, p1.ident(1));
1465
+ try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
1464
1466
  expected = switch (endian) {
1465
- .Big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1466
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1467
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1468
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1467
1469
  };
1468
1470
  try expectLog1(expected, buf[0..9]);
1469
1471
  stream.reset();
@@ -1473,10 +1475,10 @@ test "|-heal|" {
1473
1475
  var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
1474
1476
  chansey.hp = 612;
1475
1477
  chansey.status = gen1.Status.slp(1);
1476
- try log.heal(p2.ident(2), &chansey, .None);
1478
+ try log.heal(.{ p2.ident(2), &chansey, .None });
1477
1479
  var expected: []const u8 = switch (endian) {
1478
- .Big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1479
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1480
+ .big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1481
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1480
1482
  };
1481
1483
  try expectLog1(expected, buf[0..8]);
1482
1484
  stream.reset();
@@ -1484,33 +1486,33 @@ test "|-heal|" {
1484
1486
  chansey.hp = 100;
1485
1487
  chansey.stats.hp = 256;
1486
1488
  chansey.status = 0;
1487
- try log.heal(p2.ident(2), &chansey, .Silent);
1489
+ try log.heal(.{ p2.ident(2), &chansey, .Silent });
1488
1490
  expected = switch (endian) {
1489
- .Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1490
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1491
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1492
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1491
1493
  };
1492
1494
  try expectLog1(expected, buf[0..8]);
1493
1495
  stream.reset();
1494
1496
 
1495
- try log.drain(p2.ident(2), &chansey, p1.ident(1));
1497
+ try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
1496
1498
  expected = switch (endian) {
1497
- .Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1498
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1499
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1500
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1499
1501
  };
1500
1502
  try expectLog1(expected, buf[0..9]);
1501
1503
  stream.reset();
1502
1504
  }
1503
1505
 
1504
1506
  test "|-status|" {
1505
- try log.status(p2.ident(6), gen1.Status.init(.BRN), .None);
1507
+ try log.status(.{ p2.ident(6), gen1.Status.init(.BRN), .None });
1506
1508
  try expectLog1(&.{ N(ArgType.Status), 0b1110, 0b10000, N(Status.None) }, buf[0..4]);
1507
1509
  stream.reset();
1508
1510
 
1509
- try log.status(p2.ident(2), gen1.Status.init(.PSN), .Silent);
1511
+ try log.status(.{ p2.ident(2), gen1.Status.init(.PSN), .Silent });
1510
1512
  try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
1511
1513
  stream.reset();
1512
1514
 
1513
- try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR), M1.BodySlam);
1515
+ try log.status(.{ p1.ident(1), gen1.Status.init(.PAR), .From, M1.BodySlam });
1514
1516
  try expectLog1(
1515
1517
  &.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
1516
1518
  buf[0..5],
@@ -1519,11 +1521,11 @@ test "|-status|" {
1519
1521
  }
1520
1522
 
1521
1523
  test "|-curestatus|" {
1522
- try log.curestatus(p2.ident(6), gen1.Status.slp(7), .Message);
1524
+ try log.curestatus(.{ p2.ident(6), gen1.Status.slp(7), .Message });
1523
1525
  try expectLog1(&.{ N(ArgType.CureStatus), 0b1110, 0b111, N(CureStatus.Message) }, buf[0..4]);
1524
1526
  stream.reset();
1525
1527
 
1526
- try log.curestatus(p1.ident(2), gen1.Status.TOX, .Silent);
1528
+ try log.curestatus(.{ p1.ident(2), gen1.Status.TOX, .Silent });
1527
1529
  try expectLog1(&.{
1528
1530
  N(ArgType.CureStatus),
1529
1531
  0b0010,
@@ -1534,168 +1536,191 @@ test "|-curestatus|" {
1534
1536
  }
1535
1537
 
1536
1538
  test "|-boost|" {
1537
- try log.boost(p2.ident(6), .Speed, 2);
1539
+ try log.boost(.{ p2.ident(6), .Speed, 2 });
1538
1540
  try expectLog1(&.{ N(ArgType.Boost), 0b1110, N(Boost.Speed), 8 }, buf[0..4]);
1539
1541
  stream.reset();
1540
1542
 
1541
- try log.boost(p1.ident(2), .Rage, 1);
1543
+ try log.boost(.{ p1.ident(2), .Rage, 1 });
1542
1544
  try expectLog1(&.{ N(ArgType.Boost), 0b0010, N(Boost.Rage), 7 }, buf[0..4]);
1543
1545
  stream.reset();
1544
1546
 
1545
- try log.boost(p2.ident(3), .Defense, -2);
1547
+ try log.boost(.{ p2.ident(3), .Defense, -2 });
1546
1548
  try expectLog1(&.{ N(ArgType.Boost), 0b1011, N(Boost.Defense), 4 }, buf[0..4]);
1547
1549
  stream.reset();
1548
1550
  }
1549
1551
 
1550
1552
  test "|-clearallboost|" {
1551
- try log.clearallboost();
1553
+ try log.clearallboost(.{});
1552
1554
  try expectLog1(&.{N(ArgType.ClearAllBoost)}, buf[0..1]);
1553
1555
  stream.reset();
1554
1556
  }
1555
1557
 
1556
1558
  test "|-fail|" {
1557
- try log.fail(p2.ident(6), .None);
1559
+ try log.fail(.{ p2.ident(6), .None });
1558
1560
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.None) }, buf[0..3]);
1559
1561
  stream.reset();
1560
1562
 
1561
- try log.fail(p2.ident(6), .Sleep);
1563
+ try log.fail(.{ p2.ident(6), .Sleep });
1562
1564
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Sleep) }, buf[0..3]);
1563
1565
  stream.reset();
1564
1566
 
1565
- try log.fail(p2.ident(6), .Substitute);
1567
+ try log.fail(.{ p2.ident(6), .Substitute });
1566
1568
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Substitute) }, buf[0..3]);
1567
1569
  stream.reset();
1568
1570
 
1569
- try log.fail(p2.ident(6), .Weak);
1571
+ try log.fail(.{ p2.ident(6), .Weak });
1570
1572
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Weak) }, buf[0..3]);
1571
1573
  stream.reset();
1572
1574
  }
1573
1575
 
1574
1576
  test "|-miss|" {
1575
- try log.miss(p2.ident(4));
1577
+ try log.miss(.{p2.ident(4)});
1576
1578
  try expectLog1(&.{ N(ArgType.Miss), 0b1100 }, buf[0..2]);
1577
1579
  stream.reset();
1578
1580
  }
1579
1581
  test "|-hitcount|" {
1580
- try log.hitcount(p2.ident(1), 5);
1582
+ try log.hitcount(.{ p2.ident(1), 5 });
1581
1583
  try expectLog1(&.{ N(ArgType.HitCount), 0b1001, 5 }, buf[0..3]);
1582
1584
  stream.reset();
1583
1585
  }
1584
1586
 
1585
1587
  test "|-prepare|" {
1586
- try log.prepare(p2.ident(2), M1.Dig);
1588
+ try log.prepare(.{ p2.ident(2), M1.Dig });
1587
1589
  try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
1588
1590
  stream.reset();
1589
1591
  }
1590
1592
 
1591
1593
  test "|-mustrecharge|" {
1592
- try log.mustrecharge(p1.ident(6));
1594
+ try log.mustrecharge(.{p1.ident(6)});
1593
1595
  try expectLog1(&.{ N(ArgType.MustRecharge), 0b0110 }, buf[0..2]);
1594
1596
  stream.reset();
1595
1597
  }
1596
1598
 
1597
1599
  test "|-activate|" {
1598
- try log.activate(p1.ident(2), .Struggle);
1600
+ try log.activate(.{ p1.ident(2), .Struggle });
1599
1601
  try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Struggle) }, buf[0..3]);
1600
1602
  stream.reset();
1601
1603
 
1602
- try log.activate(p2.ident(4), .Mist);
1604
+ try log.activate(.{ p2.ident(4), .Mist });
1603
1605
  try expectLog1(&.{ N(ArgType.Activate), 0b1100, N(Activate.Mist) }, buf[0..3]);
1604
1606
  stream.reset();
1605
1607
 
1606
- try log.activate(p2.ident(6), .Substitute);
1608
+ try log.activate(.{ p2.ident(6), .Substitute });
1607
1609
  try expectLog1(&.{ N(ArgType.Activate), 0b1110, N(Activate.Substitute) }, buf[0..3]);
1608
1610
  stream.reset();
1609
1611
 
1610
- try log.activate(p1.ident(2), .Splash);
1612
+ try log.activate(.{ p1.ident(2), .Splash });
1611
1613
  try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
1612
1614
  stream.reset();
1615
+
1616
+ try log.activate(.{ p1.ident(4), .SubstituteBlock, M2.Spite });
1617
+ try expectLog1(&.{
1618
+ N(ArgType.Activate),
1619
+ 0b0100,
1620
+ N(Activate.SubstituteBlock),
1621
+ N(M2.Spite),
1622
+ }, buf[0..4]);
1623
+ stream.reset();
1624
+
1625
+ try log.activate(.{ p1.ident(3), .Magnitude, 5 });
1626
+ try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
1627
+ stream.reset();
1613
1628
  }
1614
1629
 
1615
1630
  test "|-fieldactivate|" {
1616
- try log.fieldactivate();
1631
+ try log.fieldactivate(.{});
1617
1632
  try expectLog1(&.{N(ArgType.FieldActivate)}, buf[0..1]);
1618
1633
  stream.reset();
1619
1634
  }
1620
1635
 
1621
1636
  test "|-start|" {
1622
- try log.start(p2.ident(6), .Bide);
1637
+ try log.start(.{ p2.ident(6), .Bide });
1623
1638
  try expectLog1(&.{ N(ArgType.Start), 0b1110, N(Start.Bide) }, buf[0..3]);
1624
1639
  stream.reset();
1625
1640
 
1626
- try log.start(p1.ident(2), .ConfusionSilent);
1641
+ try log.start(.{ p1.ident(2), .ConfusionSilent });
1627
1642
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.ConfusionSilent) }, buf[0..3]);
1628
1643
  stream.reset();
1629
1644
 
1630
- try log.typechange(p2.ident(6), gen1.Types{ .type1 = .Fire, .type2 = .Fire }, p2.ident(5));
1645
+ try log.start(.{
1646
+ p2.ident(6),
1647
+ .TypeChange,
1648
+ gen1.Types{ .type1 = .Fire, .type2 = .Fire },
1649
+ p2.ident(5),
1650
+ });
1631
1651
  try expectLog1(
1632
1652
  &.{ N(ArgType.Start), 0b1110, N(Start.TypeChange), 0b1000_1000, 0b1101 },
1633
1653
  buf[0..5],
1634
1654
  );
1635
1655
  stream.reset();
1636
1656
 
1637
- try log.typechange(p1.ident(2), gen1.Types{ .type1 = .Bug, .type2 = .Poison }, p2.ident(4));
1657
+ try log.start(.{
1658
+ p1.ident(2),
1659
+ .TypeChange,
1660
+ gen1.Types{ .type1 = .Bug, .type2 = .Poison },
1661
+ p2.ident(4),
1662
+ });
1638
1663
  try expectLog1(
1639
1664
  &.{ N(ArgType.Start), 0b0010, N(Start.TypeChange), 0b0011_0110, 0b1100 },
1640
1665
  buf[0..5],
1641
1666
  );
1642
1667
  stream.reset();
1643
1668
 
1644
- try log.startEffect(p1.ident(2), .Disable, M1.Surf);
1669
+ try log.start(.{ p1.ident(2), .Disable, M1.Surf });
1645
1670
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
1646
1671
  stream.reset();
1647
1672
 
1648
- try log.startEffect(p1.ident(2), .Mimic, M1.Surf);
1673
+ try log.start(.{ p1.ident(2), .Mimic, M1.Surf });
1649
1674
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
1650
1675
  stream.reset();
1651
1676
  }
1652
1677
 
1653
1678
  test "|-end|" {
1654
- try log.end(p2.ident(6), .Bide);
1679
+ try log.end(.{ p2.ident(6), .Bide });
1655
1680
  try expectLog1(&.{ N(ArgType.End), 0b1110, N(End.Bide) }, buf[0..3]);
1656
1681
  stream.reset();
1657
1682
 
1658
- try log.end(p1.ident(2), .ConfusionSilent);
1683
+ try log.end(.{ p1.ident(2), .ConfusionSilent });
1659
1684
  try expectLog1(&.{ N(ArgType.End), 0b0010, N(End.ConfusionSilent) }, buf[0..3]);
1660
1685
  stream.reset();
1661
1686
  }
1662
1687
 
1663
1688
  test "|-ohko|" {
1664
- try log.ohko();
1689
+ try log.ohko(.{});
1665
1690
  try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
1666
1691
  stream.reset();
1667
1692
  }
1668
1693
 
1669
1694
  test "|-crit|" {
1670
- try log.crit(p2.ident(5));
1695
+ try log.crit(.{p2.ident(5)});
1671
1696
  try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
1672
1697
  stream.reset();
1673
1698
  }
1674
1699
 
1675
1700
  test "|-supereffective|" {
1676
- try log.supereffective(p1.ident(1));
1701
+ try log.supereffective(.{p1.ident(1)});
1677
1702
  try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
1678
1703
  stream.reset();
1679
1704
  }
1680
1705
 
1681
1706
  test "|-resisted|" {
1682
- try log.resisted(p2.ident(2));
1707
+ try log.resisted(.{p2.ident(2)});
1683
1708
  try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
1684
1709
  stream.reset();
1685
1710
  }
1686
1711
 
1687
1712
  test "|-immune|" {
1688
- try log.immune(p1.ident(3), .None);
1713
+ try log.immune(.{ p1.ident(3), .None });
1689
1714
  try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
1690
1715
  stream.reset();
1691
1716
 
1692
- try log.immune(p2.ident(2), .OHKO);
1717
+ try log.immune(.{ p2.ident(2), .OHKO });
1693
1718
  try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
1694
1719
  stream.reset();
1695
1720
  }
1696
1721
 
1697
1722
  test "|-transform|" {
1698
- try log.transform(p2.ident(4), p1.ident(5));
1723
+ try log.transform(.{ p2.ident(4), p1.ident(5) });
1699
1724
  try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
1700
1725
  stream.reset();
1701
1726
  }
@@ -1706,7 +1731,7 @@ test "|drag|" {
1706
1731
  blissey.hp = 200;
1707
1732
  blissey.stats.hp = 400;
1708
1733
  blissey.status = gen2.Status.init(.PAR);
1709
- try log.drag(p2.ident(3), &blissey);
1734
+ try log.drag(.{ p2.ident(3), &blissey });
1710
1735
  const par = 0b1000000;
1711
1736
  const expected = &(.{
1712
1737
  N(ArgType.Drag),
@@ -1715,31 +1740,31 @@ test "|drag|" {
1715
1740
  N(gen2.Gender.Female),
1716
1741
  91,
1717
1742
  } ++ switch (endian) {
1718
- .Big => .{ 0, 200, 1, 144, par },
1719
- .Little => .{ 200, 0, 144, 1, par },
1743
+ .big => .{ 0, 200, 1, 144, par },
1744
+ .little => .{ 200, 0, 144, 1, par },
1720
1745
  });
1721
1746
  try expectLog2(expected, buf[0..10]);
1722
1747
  stream.reset();
1723
1748
  }
1724
1749
 
1725
1750
  test "|-item|" {
1726
- try log.item(p2.ident(2), I2.GoldBerry, p1.ident(4));
1751
+ try log.item(.{ p2.ident(2), I2.GoldBerry, p1.ident(4) });
1727
1752
  try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
1728
1753
  stream.reset();
1729
1754
  }
1730
1755
 
1731
1756
  test "|-enditem|" {
1732
- try log.enditem(p1.ident(1), I2.BerserkGene, .None);
1757
+ try log.enditem(.{ p1.ident(1), I2.BerserkGene, .None });
1733
1758
  try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
1734
1759
  stream.reset();
1735
1760
 
1736
- try log.enditem(p2.ident(4), I2.PRZCureBerry, .Eat);
1761
+ try log.enditem(.{ p2.ident(4), I2.PRZCureBerry, .Eat });
1737
1762
  try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
1738
1763
  stream.reset();
1739
1764
  }
1740
1765
 
1741
1766
  test "|-cureteam|" {
1742
- try log.cureteam(p2.ident(5));
1767
+ try log.cureteam(.{p2.ident(5)});
1743
1768
  try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
1744
1769
  stream.reset();
1745
1770
  }
@@ -1747,71 +1772,70 @@ test "|-cureteam|" {
1747
1772
  test "|-sethp|" {
1748
1773
  var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
1749
1774
  blissey.hp = 612;
1750
- try log.sethp(p2.ident(2), &blissey, .Silent);
1751
- var expected: []const u8 = switch (endian) {
1752
- .Big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1753
- .Little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1775
+ try log.sethp(.{ p2.ident(2), &blissey, .Silent });
1776
+ const expected: []const u8 = switch (endian) {
1777
+ .big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1778
+ .little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1754
1779
  };
1755
1780
  try expectLog2(expected, buf[0..8]);
1756
1781
  stream.reset();
1757
1782
  }
1758
1783
 
1759
1784
  test "|-setboost|" {
1760
- try log.setboost(p2.ident(6), 6);
1785
+ try log.setboost(.{ p2.ident(6), 6 });
1761
1786
  try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
1762
1787
  stream.reset();
1763
1788
 
1764
- try log.setboost(p2.ident(3), 2);
1789
+ try log.setboost(.{ p2.ident(3), 2 });
1765
1790
  try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
1766
1791
  stream.reset();
1767
1792
  }
1768
1793
 
1769
1794
  test "|-copyboost|" {
1770
- try log.copyboost(p2.ident(3), p1.ident(6));
1795
+ try log.copyboost(.{ p2.ident(3), p1.ident(6) });
1771
1796
  try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
1772
1797
  stream.reset();
1773
1798
  }
1774
1799
 
1775
1800
  test "|-sidestart|" {
1776
- try log.sidestart(.P2, .Reflect);
1801
+ try log.sidestart(.{ .P2, .Reflect });
1777
1802
  try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
1778
1803
  stream.reset();
1779
1804
  }
1780
1805
 
1781
1806
  test "|-sideend|" {
1782
- try log.sideend(.P2, .LightScreen);
1807
+ try log.sideend(.{ .P2, .LightScreen });
1783
1808
  try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
1784
1809
  stream.reset();
1785
1810
 
1786
- try log.spikesend(.P1, M2.RapidSpin, p1.ident(3));
1811
+ try log.sideend(.{ .P1, .Spikes, p1.ident(3) });
1787
1812
  try expectLog2(&.{
1788
1813
  N(ArgType.SideEnd),
1789
1814
  0,
1790
1815
  N(Side.Spikes),
1791
- N(M2.RapidSpin),
1792
1816
  0b0011,
1793
- }, buf[0..5]);
1817
+ }, buf[0..4]);
1794
1818
  stream.reset();
1795
1819
  }
1796
1820
 
1797
1821
  test "|-singlemove|" {
1798
- try log.singlemove(p2.ident(2), M2.DestinyBond);
1822
+ try log.singlemove(.{ p2.ident(2), M2.DestinyBond });
1799
1823
  try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
1800
1824
  stream.reset();
1801
1825
  }
1802
1826
 
1803
1827
  test "|-singleturn|" {
1804
- try log.singleturn(p1.ident(3), M2.Protect);
1828
+ try log.singleturn(.{ p1.ident(3), M2.Protect });
1805
1829
  try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
1806
1830
  stream.reset();
1807
1831
  }
1808
1832
 
1809
1833
  test "|-weather|" {
1810
- try log.weather(W2.Rain, .Upkeep);
1834
+ try log.weather(.{ W2.Rain, .Upkeep });
1811
1835
  try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
1812
1836
  stream.reset();
1813
1837
 
1814
- try log.weather(W2.None, .None);
1838
+ try log.weather(.{ W2.None, .None });
1815
1839
  try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
1816
1840
  stream.reset();
1817
1841
  }