@pkmn/engine 0.1.0-dev.900756a9 → 0.1.0-dev.9257876b

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.
@@ -1,8 +1,10 @@
1
1
  const std = @import("std");
2
2
  const builtin = @import("builtin");
3
3
 
4
- const data = @import("./data.zig");
5
- const options = @import("./options.zig");
4
+ const pkmn = @import("../pkmn.zig");
5
+
6
+ const data = @import("data.zig");
7
+ const options = @import("options.zig");
6
8
 
7
9
  const assert = std.debug.assert;
8
10
  const print = std.debug.print;
@@ -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,
@@ -215,6 +220,7 @@ pub const Activate = enum(u8) {
215
220
  BeatUp, // FIXME of
216
221
 
217
222
  Magnitude,
223
+ Spite,
218
224
  };
219
225
 
220
226
  pub const Start = enum(u8) {
@@ -320,530 +326,488 @@ pub fn Log(comptime Writer: type) type {
320
326
 
321
327
  pub const Error = Writer.Error;
322
328
 
323
- pub fn move(self: Self, source: ID, m: anytype, target: ID) Error!void {
329
+ // source: ID, move: <Move>, target: ID, from?: <Move>
330
+ pub fn move(self: Self, args: anytype) Error!void {
324
331
  if (!enabled) return;
325
332
 
326
- assert(m != .None);
333
+ assert(args[1] != .None);
327
334
  try self.writer.writeAll(&.{
328
335
  @intFromEnum(ArgType.Move),
329
- @as(u8, @bitCast(source)),
330
- @intFromEnum(m),
331
- @as(u8, @bitCast(target)),
332
- @intFromEnum(Move.None),
336
+ @as(u8, @bitCast(args[0])),
337
+ @intFromEnum(args[1]),
338
+ @as(u8, @bitCast(args[2])),
333
339
  });
334
- }
335
-
336
- pub fn moveFrom(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
337
- if (!enabled) return;
338
-
339
- assert(m != .None);
340
- try self.writer.writeAll(&.{
341
- @intFromEnum(ArgType.Move),
342
- @as(u8, @bitCast(source)),
343
- @intFromEnum(m),
344
- @as(u8, @bitCast(target)),
345
- });
346
- try self.writer.writeAll(if (@intFromEnum(from) == 0)
340
+ try self.writer.writeAll(if (args.len < 4 or @intFromEnum(args[3]) == 0)
347
341
  &.{@intFromEnum(Move.None)}
348
342
  else
349
- &.{ @intFromEnum(Move.From), @intFromEnum(from) });
343
+ &.{ @intFromEnum(Move.From), @intFromEnum(args[3]) });
350
344
  }
351
345
 
352
- pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void {
353
- return switchDrag(self, .Switch, ident, pokemon);
346
+ // ident: ID, pokemon: <Pokemon>
347
+ pub fn switched(self: Self, args: anytype) Error!void {
348
+ return switchDrag(self, .Switch, args);
354
349
  }
355
350
 
356
- fn switchDrag(self: Self, arg: ArgType, ident: ID, pokemon: anytype) Error!void {
351
+ // ident: ID, pokemon: <Pokemon>
352
+ fn switchDrag(self: Self, arg: ArgType, args: anytype) Error!void {
357
353
  if (!enabled) return;
358
354
 
359
- try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(ident)) });
360
- if (@hasField(@TypeOf(pokemon.*), "dvs")) {
355
+ try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(args[0])) });
356
+ if (@hasField(@TypeOf(args[1].*), "dvs")) {
361
357
  try self.writer.writeAll(&.{
362
- @intFromEnum(pokemon.species),
363
- @intFromEnum(pokemon.dvs.gender),
364
- pokemon.level,
358
+ @intFromEnum(args[1].species),
359
+ @intFromEnum(args[1].dvs.gender),
360
+ args[1].level,
365
361
  });
366
362
  } else {
367
- try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level });
363
+ try self.writer.writeAll(&.{ @intFromEnum(args[1].species), args[1].level });
368
364
  }
369
- try self.writer.writeIntNative(u16, pokemon.hp);
370
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
371
- try self.writer.writeAll(&.{pokemon.status});
372
- }
373
-
374
- pub fn cant(self: Self, ident: ID, reason: Cant) Error!void {
375
- if (!enabled) return;
376
-
377
- assert(reason != .Disable);
378
- try self.writer.writeAll(&.{
379
- @intFromEnum(ArgType.Cant),
380
- @as(u8, @bitCast(ident)),
381
- @intFromEnum(reason),
382
- });
365
+ try self.writer.writeInt(u16, args[1].hp, endian);
366
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
367
+ try self.writer.writeAll(&.{args[1].status});
383
368
  }
384
369
 
385
- pub fn disabled(self: Self, ident: ID, m: anytype) Error!void {
370
+ // ident: ID, reason: Cant
371
+ // ident: ID, reason: .Disable, move: <Move>
372
+ pub fn cant(self: Self, args: anytype) Error!void {
386
373
  if (!enabled) return;
387
374
 
375
+ assert(args[1] != .Disable or args.len == 3);
388
376
  try self.writer.writeAll(&.{
389
377
  @intFromEnum(ArgType.Cant),
390
- @as(u8, @bitCast(ident)),
391
- @intFromEnum(Cant.Disable),
392
- @intFromEnum(m),
378
+ @as(u8, @bitCast(args[0])),
379
+ @intFromEnum(@as(Cant, args[1])),
393
380
  });
381
+ if (args.len == 3) try self.writer.writeByte(@intFromEnum(args[2]));
394
382
  }
395
383
 
396
- pub fn faint(self: Self, ident: ID, done: bool) Error!void {
384
+ // ident: ID, done: bool
385
+ pub fn faint(self: Self, args: anytype) Error!void {
397
386
  if (!enabled) return;
398
387
 
399
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) });
400
- if (done) try self.writer.writeByte(@intFromEnum(ArgType.None));
388
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(args[0])) });
389
+ if (args[1]) try self.writer.writeByte(@intFromEnum(ArgType.None));
401
390
  }
402
391
 
403
- pub fn turn(self: Self, num: u16) Error!void {
392
+ // num: u16
393
+ pub fn turn(self: Self, args: anytype) Error!void {
404
394
  if (!enabled) return;
405
395
 
406
396
  try self.writer.writeByte(@intFromEnum(ArgType.Turn));
407
- try self.writer.writeIntNative(u16, num);
397
+ try self.writer.writeInt(u16, args[0], endian);
408
398
  try self.writer.writeByte(@intFromEnum(ArgType.None));
409
399
  }
410
400
 
411
- pub fn win(self: Self, player: Player) Error!void {
401
+ // player: Player
402
+ pub fn win(self: Self, args: anytype) Error!void {
412
403
  if (!enabled) return;
413
404
 
414
405
  try self.writer.writeAll(&.{
415
406
  @intFromEnum(ArgType.Win),
416
- @intFromEnum(player),
407
+ @intFromEnum(@as(Player, args[0])),
417
408
  @intFromEnum(ArgType.None),
418
409
  });
419
410
  }
420
411
 
421
- pub fn tie(self: Self) Error!void {
412
+ // -
413
+ pub fn tie(self: Self, _: anytype) Error!void {
422
414
  if (!enabled) return;
423
415
 
424
416
  try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
425
417
  }
426
418
 
427
- pub fn damage(self: Self, ident: ID, pokemon: anytype, reason: Damage) Error!void {
419
+ // ident: ID, pokemon: <Pokemon>, reason: Damage
420
+ // ident: ID, pokemon: <Pokemon>, reason: .RecoilOf, source: ID
421
+ pub fn damage(self: Self, args: anytype) Error!void {
428
422
  if (!enabled) return;
429
423
 
430
- assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed));
431
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
432
- try self.writer.writeIntNative(u16, pokemon.hp);
433
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
434
- try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
435
- }
436
-
437
- pub fn damageOf(
438
- self: Self,
439
- ident: ID,
440
- pokemon: anytype,
441
- reason: Damage,
442
- source: ID,
443
- ) Error!void {
444
- if (!enabled) return;
445
-
446
- assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf));
447
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
448
- try self.writer.writeIntNative(u16, pokemon.hp);
449
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
424
+ assert(args[2] != .RecoilOf or args.len == 4);
450
425
  try self.writer.writeAll(&.{
451
- pokemon.status,
452
- @intFromEnum(reason),
453
- @as(u8, @bitCast(source)),
426
+ @intFromEnum(ArgType.Damage),
427
+ @as(u8, @bitCast(args[0])),
454
428
  });
429
+ try self.writer.writeInt(u16, args[1].hp, endian);
430
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
431
+ try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Damage, args[2])) });
432
+ if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
455
433
  }
456
434
 
457
- // args: ident: ID, pokemon: anytype, reason: Heal
435
+ // ident: ID, pokemon: <Pokemon>, reason: Heal
436
+ // ident: ID, pokemon: <Pokemon>, reason: .Drain, target: ID
458
437
  pub fn heal(self: Self, args: anytype) Error!void {
459
438
  if (!enabled) return;
460
439
 
461
- assert(args[2] != .Drain);
440
+ assert(args[2] != .Drain or args.len == 4);
462
441
  try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
463
- try self.writer.writeIntNative(u16, args[1].hp);
464
- try self.writer.writeIntNative(u16, args[1].stats.hp);
465
- try self.writer.writeAll(&.{ args[1].status, @intFromEnum(args[2]) });
466
- }
467
-
468
- pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
469
- if (!enabled) return;
470
-
471
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
472
- try self.writer.writeIntNative(u16, pokemon.hp);
473
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
474
- try self.writer.writeAll(&.{
475
- pokemon.status,
476
- @intFromEnum(Heal.Drain),
477
- @as(u8, @bitCast(target)),
478
- });
442
+ try self.writer.writeInt(u16, args[1].hp, endian);
443
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
444
+ try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Heal, args[2])) });
445
+ if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
479
446
  }
480
447
 
481
- pub fn status(self: Self, ident: ID, value: u8, reason: Status) Error!void {
448
+ // ident: ID, value: u8, reason: Status
449
+ // ident: ID, value: u8, reason: .From, m: <Move>
450
+ pub fn status(self: Self, args: anytype) Error!void {
482
451
  if (!enabled) return;
483
452
 
484
- assert(reason != .From);
453
+ assert(args[2] != .From or args.len == 4);
485
454
  try self.writer.writeAll(&.{
486
455
  @intFromEnum(ArgType.Status),
487
- @as(u8, @bitCast(ident)),
488
- value,
489
- @intFromEnum(reason),
456
+ @as(u8, @bitCast(args[0])),
457
+ args[1],
458
+ @intFromEnum(@as(Status, args[2])),
490
459
  });
460
+ if (args.len == 4) try self.writer.writeByte(@intFromEnum(args[3]));
491
461
  }
492
462
 
493
- pub fn statusFrom(self: Self, ident: ID, value: u8, m: anytype) Error!void {
494
- if (!enabled) return;
495
-
496
- try self.writer.writeAll(&.{
497
- @intFromEnum(ArgType.Status),
498
- @as(u8, @bitCast(ident)),
499
- value,
500
- @intFromEnum(Status.From),
501
- @intFromEnum(m),
502
- });
503
- }
504
-
505
- pub fn curestatus(self: Self, ident: ID, value: u8, reason: CureStatus) Error!void {
463
+ // ident: ID, value: u8, reason: CureStatus
464
+ pub fn curestatus(self: Self, args: anytype) Error!void {
506
465
  if (!enabled) return;
507
466
 
508
467
  try self.writer.writeAll(&.{
509
468
  @intFromEnum(ArgType.CureStatus),
510
- @as(u8, @bitCast(ident)),
511
- value,
512
- @intFromEnum(reason),
469
+ @as(u8, @bitCast(args[0])),
470
+ args[1],
471
+ @intFromEnum(@as(CureStatus, args[2])),
513
472
  });
514
473
  }
515
474
 
516
- pub fn boost(self: Self, ident: ID, reason: Boost, num: i8) Error!void {
475
+ // ident: ID, reason: Boost, num: i8
476
+ pub fn boost(self: Self, args: anytype) Error!void {
517
477
  if (!enabled) return;
518
478
 
519
- assert(num != 0 and (reason != .Rage or num > 0));
479
+ assert(args[2] != 0 and (args[1] != .Rage or args[2] > 0));
520
480
  try self.writer.writeAll(&.{
521
481
  @intFromEnum(ArgType.Boost),
522
- @as(u8, @bitCast(ident)),
523
- @intFromEnum(reason),
524
- @as(u8, @intCast(num + 6)),
482
+ @as(u8, @bitCast(args[0])),
483
+ @intFromEnum(@as(Boost, args[1])),
484
+ @as(u8, @intCast(@as(i8, args[2]) + 6)),
525
485
  });
526
486
  }
527
487
 
528
- pub fn clearallboost(self: Self) Error!void {
488
+ // -
489
+ pub fn clearallboost(self: Self, _: anytype) Error!void {
529
490
  if (!enabled) return;
530
491
 
531
492
  try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
532
493
  }
533
494
 
534
- pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
495
+ // ident: ID, reason: Fail
496
+ pub fn fail(self: Self, args: anytype) Error!void {
535
497
  if (!enabled) return;
536
498
 
537
499
  try self.writer.writeAll(&.{
538
500
  @intFromEnum(ArgType.Fail),
539
- @as(u8, @bitCast(ident)),
540
- @intFromEnum(reason),
501
+ @as(u8, @bitCast(args[0])),
502
+ @intFromEnum(@as(Fail, args[1])),
541
503
  });
542
504
  }
543
505
 
544
- pub fn miss(self: Self, source: ID) Error!void {
506
+ // source: ID
507
+ pub fn miss(self: Self, args: anytype) Error!void {
545
508
  if (!enabled) return;
546
509
 
547
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) });
510
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(args[0])) });
548
511
  }
549
512
 
550
- pub fn hitcount(self: Self, ident: ID, num: u8) Error!void {
513
+ // ident: ID, num: u8
514
+ pub fn hitcount(self: Self, args: anytype) Error!void {
551
515
  if (!enabled) return;
552
516
 
553
517
  try self.writer.writeAll(&.{
554
518
  @intFromEnum(ArgType.HitCount),
555
- @as(u8, @bitCast(ident)),
556
- num,
519
+ @as(u8, @bitCast(args[0])),
520
+ args[1],
557
521
  });
558
522
  }
559
523
 
560
- pub fn prepare(self: Self, source: ID, m: anytype) Error!void {
524
+ // source: ID, m: <Move>
525
+ pub fn prepare(self: Self, args: anytype) Error!void {
561
526
  if (!enabled) return;
562
527
 
563
528
  try self.writer.writeAll(&.{
564
529
  @intFromEnum(ArgType.Prepare),
565
- @as(u8, @bitCast(source)),
566
- @intFromEnum(m),
530
+ @as(u8, @bitCast(args[0])),
531
+ @intFromEnum(args[1]),
567
532
  });
568
533
  }
569
534
 
570
- pub fn mustrecharge(self: Self, ident: ID) Error!void {
535
+ // ident: ID
536
+ pub fn mustrecharge(self: Self, args: anytype) Error!void {
571
537
  if (!enabled) return;
572
538
 
573
539
  try self.writer.writeAll(&.{
574
540
  @intFromEnum(ArgType.MustRecharge),
575
- @as(u8, @bitCast(ident)),
541
+ @as(u8, @bitCast(args[0])),
576
542
  });
577
543
  }
578
544
 
579
- pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
545
+ // ident: ID, reason: Activate
546
+ // ident: ID, reason: .SubstituteBlock, m: <Move>
547
+ // ident: ID, reason: .Magnitude, num: u8
548
+ // ident: ID, reason: .Spite, m: <Move>, num: u8
549
+ pub fn activate(self: Self, args: anytype) Error!void {
580
550
  if (!enabled) return;
581
551
 
582
- assert(reason != .SubstituteBlock); // TODO
552
+ assert(args.len <= 4);
553
+ const reason: Activate = args[1];
583
554
  try self.writer.writeAll(&.{
584
555
  @intFromEnum(ArgType.Activate),
585
- @as(u8, @bitCast(ident)),
556
+ @as(u8, @bitCast(args[0])),
586
557
  @intFromEnum(reason),
587
558
  });
559
+ if (args.len == 3) {
560
+ if (reason == .SubstituteBlock) {
561
+ try self.writer.writeByte(@intFromEnum(args[2]));
562
+ } else {
563
+ assert(reason == .Magnitude);
564
+ try self.writer.writeByte(args[2]);
565
+ }
566
+ } else if (args.len == 4) {
567
+ assert(reason == .Spite);
568
+ try self.writer.writeAll(&.{ @intFromEnum(args[2]), args[3] });
569
+ }
588
570
  }
589
571
 
590
- pub fn activateMove(self: Self, ident: ID, reason: Activate, m: anytype) Error!void {
591
- if (!enabled) return;
592
-
593
- assert(reason == .SubstituteBlock); // TODO
594
- try self.writer.writeAll(&.{
595
- @intFromEnum(ArgType.Activate),
596
- @as(u8, @bitCast(ident)),
597
- @intFromEnum(reason),
598
- @intFromEnum(m),
599
- });
600
- }
601
-
602
- pub fn magnitude(self: Self, ident: ID, num: u8) Error!void {
603
- if (!enabled) return;
604
-
605
- try self.writer.writeAll(&.{
606
- @intFromEnum(ArgType.Activate),
607
- @as(u8, @bitCast(ident)),
608
- @intFromEnum(Activate.Magnitude),
609
- num,
610
- });
611
- }
612
-
613
- pub fn fieldactivate(self: Self) Error!void {
572
+ // -
573
+ pub fn fieldactivate(self: Self, _: anytype) Error!void {
614
574
  if (!enabled) return;
615
575
 
616
576
  try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
617
577
  }
618
578
 
619
- pub fn start(self: Self, ident: ID, reason: Start) Error!void {
620
- if (!enabled) return;
621
-
622
- assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
623
- try self.writer.writeAll(&.{
624
- @intFromEnum(ArgType.Start),
625
- @as(u8, @bitCast(ident)),
626
- @intFromEnum(reason),
627
- });
628
- }
629
-
630
- pub fn typechange(self: Self, source: ID, types: anytype, target: ID) Error!void {
579
+ // ident: ID, reason: Start
580
+ // ident: ID, reason: .Disable | .Mimic | .Encore, m: <Move>
581
+ // ident: ID, reason: .TypeChange, types: <Types>, target: ID
582
+ pub fn start(self: Self, args: anytype) Error!void {
631
583
  if (!enabled) return;
632
584
 
585
+ assert(args.len <= 4);
586
+ const reason: Start = args[1];
633
587
  try self.writer.writeAll(&.{
634
588
  @intFromEnum(ArgType.Start),
635
- @as(u8, @bitCast(source)),
636
- @intFromEnum(Start.TypeChange),
637
- @as(u8, @bitCast(types)),
638
- @as(u8, @bitCast(target)),
639
- });
640
- }
641
-
642
- pub fn startEffect(self: Self, ident: ID, reason: Start, m: anytype) Error!void {
643
- if (!enabled) return;
644
-
645
- assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
646
- try self.writer.writeAll(&.{
647
- @intFromEnum(ArgType.Start),
648
- @as(u8, @bitCast(ident)),
589
+ @as(u8, @bitCast(args[0])),
649
590
  @intFromEnum(reason),
650
- @intFromEnum(m),
651
591
  });
592
+ if (args.len == 3) {
593
+ assert(reason == .Disable or reason == .Mimic or reason == .Encore);
594
+ try self.writer.writeByte(@intFromEnum(args[2]));
595
+ } else if (args.len == 4) {
596
+ assert(reason == .TypeChange);
597
+ // FIXME: u16 types in Generation II
598
+ try self.writer.writeAll(&.{
599
+ @as(u8, @bitCast(args[2])),
600
+ @as(u8, @bitCast(args[3])),
601
+ });
602
+ }
652
603
  }
653
604
 
654
- pub fn end(self: Self, ident: ID, reason: End) Error!void {
605
+ // ident: ID, reason: End
606
+ pub fn end(self: Self, args: anytype) Error!void {
655
607
  if (!enabled) return;
656
608
 
657
609
  try self.writer.writeAll(&.{
658
610
  @intFromEnum(ArgType.End),
659
- @as(u8, @bitCast(ident)),
660
- @intFromEnum(reason),
611
+ @as(u8, @bitCast(args[0])),
612
+ @intFromEnum(@as(End, args[1])),
661
613
  });
662
614
  }
663
615
 
664
- pub fn ohko(self: Self) Error!void {
616
+ // -
617
+ pub fn ohko(self: Self, _: anytype) Error!void {
665
618
  if (!enabled) return;
666
619
 
667
620
  try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
668
621
  }
669
622
 
670
- pub fn crit(self: Self, ident: ID) Error!void {
623
+ // ident: ID
624
+ pub fn crit(self: Self, args: anytype) Error!void {
671
625
  if (!enabled) return;
672
626
 
673
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) });
627
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(args[0])) });
674
628
  }
675
629
 
676
- pub fn supereffective(self: Self, ident: ID) Error!void {
630
+ // ident: ID
631
+ pub fn supereffective(self: Self, args: anytype) Error!void {
677
632
  if (!enabled) return;
678
633
 
679
634
  try self.writer.writeAll(&.{
680
635
  @intFromEnum(ArgType.SuperEffective),
681
- @as(u8, @bitCast(ident)),
636
+ @as(u8, @bitCast(args[0])),
682
637
  });
683
638
  }
684
639
 
685
- pub fn resisted(self: Self, ident: ID) Error!void {
640
+ // ident: ID
641
+ pub fn resisted(self: Self, args: anytype) Error!void {
686
642
  if (!enabled) return;
687
643
 
688
644
  try self.writer.writeAll(&.{
689
645
  @intFromEnum(ArgType.Resisted),
690
- @as(u8, @bitCast(ident)),
646
+ @as(u8, @bitCast(args[0])),
691
647
  });
692
648
  }
693
649
 
694
- pub fn immune(self: Self, ident: ID, reason: Immune) Error!void {
650
+ // ident: ID, reason: Immune
651
+ pub fn immune(self: Self, args: anytype) Error!void {
695
652
  if (!enabled) return;
696
653
 
697
654
  try self.writer.writeAll(&.{
698
655
  @intFromEnum(ArgType.Immune),
699
- @as(u8, @bitCast(ident)),
700
- @intFromEnum(reason),
656
+ @as(u8, @bitCast(args[0])),
657
+ @intFromEnum(@as(Immune, args[1])),
701
658
  });
702
659
  }
703
660
 
704
- pub fn transform(self: Self, source: ID, target: ID) Error!void {
661
+ // source: ID, target: ID
662
+ pub fn transform(self: Self, args: anytype) Error!void {
705
663
  if (!enabled) return;
706
664
 
707
665
  try self.writer.writeAll(&.{
708
666
  @intFromEnum(ArgType.Transform),
709
- @as(u8, @bitCast(source)),
710
- @as(u8, @bitCast(target)),
667
+ @as(u8, @bitCast(args[0])),
668
+ @as(u8, @bitCast(args[1])),
711
669
  });
712
670
  }
713
671
 
714
- pub fn drag(self: Self, ident: ID, pokemon: anytype) Error!void {
715
- return switchDrag(self, .Drag, ident, pokemon);
672
+ // ident: ID, pokemon: <Pokemon>
673
+ pub fn drag(self: Self, args: anytype) Error!void {
674
+ return switchDrag(self, .Drag, args);
716
675
  }
717
676
 
718
- pub fn item(self: Self, target: ID, i: anytype, source: ID) Error!void {
677
+ // target: ID, item: <Item>, source: ID
678
+ pub fn item(self: Self, args: anytype) Error!void {
719
679
  if (!enabled) return;
720
680
 
721
681
  try self.writer.writeAll(&.{
722
682
  @intFromEnum(ArgType.Item),
723
- @as(u8, @bitCast(target)),
724
- @intFromEnum(i),
725
- @as(u8, @bitCast(source)),
683
+ @as(u8, @bitCast(args[0])),
684
+ @intFromEnum(args[1]),
685
+ @as(u8, @bitCast(args[2])),
726
686
  });
727
687
  }
728
688
 
729
- pub fn enditem(self: Self, ident: ID, i: anytype, reason: EndItem) Error!void {
689
+ // ident: ID, item: <Item>, reason: EndItem
690
+ pub fn enditem(self: Self, args: anytype) Error!void {
730
691
  if (!enabled) return;
731
692
 
732
693
  try self.writer.writeAll(&.{
733
694
  @intFromEnum(ArgType.EndItem),
734
- @as(u8, @bitCast(ident)),
735
- @intFromEnum(i),
736
- @intFromEnum(reason),
695
+ @as(u8, @bitCast(args[0])),
696
+ @intFromEnum(args[1]),
697
+ @intFromEnum(@as(EndItem, args[2])),
737
698
  });
738
699
  }
739
700
 
740
- pub fn cureteam(self: Self, source: ID) Error!void {
701
+ // source: ID
702
+ pub fn cureteam(self: Self, args: anytype) Error!void {
741
703
  if (!enabled) return;
742
704
 
743
705
  try self.writer.writeAll(&.{
744
706
  @intFromEnum(ArgType.CureTeam),
745
- @as(u8, @bitCast(source)),
707
+ @as(u8, @bitCast(args[0])),
746
708
  });
747
709
  }
748
710
 
749
- pub fn sethp(self: Self, ident: ID, pokemon: anytype, reason: SetHP) Error!void {
711
+ // ident: ID, pokemon: <Pokemon>, reason: SetHP
712
+ pub fn sethp(self: Self, args: anytype) Error!void {
750
713
  if (!enabled) return;
751
714
 
752
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(ident)) });
753
- try self.writer.writeIntNative(u16, pokemon.hp);
754
- try self.writer.writeIntNative(u16, pokemon.stats.hp);
755
- try self.writer.writeAll(&.{pokemon.status});
756
- try self.writer.writeByte(@intFromEnum(reason));
715
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(args[0])) });
716
+ try self.writer.writeInt(u16, args[1].hp, endian);
717
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
718
+ try self.writer.writeAll(&.{args[1].status});
719
+ try self.writer.writeByte(@intFromEnum(@as(SetHP, args[2])));
757
720
  }
758
721
 
759
- pub fn setboost(self: Self, ident: ID, num: i8) Error!void {
722
+ // ident: ID, num: i8
723
+ pub fn setboost(self: Self, args: anytype) Error!void {
760
724
  if (!enabled) return;
761
725
 
762
726
  try self.writer.writeAll(&.{
763
727
  @intFromEnum(ArgType.SetBoost),
764
- @as(u8, @bitCast(ident)),
765
- @as(u8, @intCast(num + 6)),
728
+ @as(u8, @bitCast(args[0])),
729
+ @as(u8, @intCast(args[1] + 6)),
766
730
  });
767
731
  }
768
732
 
769
- pub fn copyboost(self: Self, source: ID, target: ID) Error!void {
733
+ // source: ID, target: ID
734
+ pub fn copyboost(self: Self, args: anytype) Error!void {
770
735
  if (!enabled) return;
771
736
 
772
737
  try self.writer.writeAll(&.{
773
738
  @intFromEnum(ArgType.CopyBoost),
774
- @as(u8, @bitCast(source)),
775
- @as(u8, @bitCast(target)),
739
+ @as(u8, @bitCast(args[0])),
740
+ @as(u8, @bitCast(args[1])),
776
741
  });
777
742
  }
778
743
 
779
- pub fn sidestart(self: Self, player: Player, reason: Side) Error!void {
744
+ // player: Player, reason: Side
745
+ pub fn sidestart(self: Self, args: anytype) Error!void {
780
746
  if (!enabled) return;
781
747
 
782
748
  try self.writer.writeAll(&.{
783
749
  @intFromEnum(ArgType.SideStart),
784
- @intFromEnum(player),
785
- @intFromEnum(reason),
750
+ @intFromEnum(@as(Player, args[0])),
751
+ @intFromEnum(@as(Side, args[1])),
786
752
  });
787
753
  }
788
754
 
789
- pub fn sideend(self: Self, player: Player, reason: Side) Error!void {
755
+ // player: Player, reason: Side
756
+ // player: Player, reason: .Spikes, source: ID
757
+ pub fn sideend(self: Self, args: anytype) Error!void {
790
758
  if (!enabled) return;
791
759
 
792
- assert(@intFromEnum(reason) != @intFromEnum(Side.Spikes));
760
+ assert(args[1] != .Spikes or args.len == 3);
793
761
  try self.writer.writeAll(&.{
794
762
  @intFromEnum(ArgType.SideEnd),
795
- @intFromEnum(player),
796
- @intFromEnum(reason),
763
+ @intFromEnum(@as(Player, args[0])),
764
+ @intFromEnum(@as(Side, args[1])),
797
765
  });
766
+ if (args.len == 3) try self.writer.writeByte(@as(u8, @bitCast(args[2])));
798
767
  }
799
768
 
800
- pub fn spikesend(self: Self, source: ID) Error!void {
801
- if (!enabled) return;
802
-
803
- try self.writer.writeAll(&.{
804
- @intFromEnum(ArgType.SideEnd),
805
- @intFromEnum(source.player),
806
- @intFromEnum(Side.Spikes),
807
- @as(u8, @bitCast(source)),
808
- });
769
+ // ident: ID, move: <Move>
770
+ pub fn singlemove(self: Self, args: anytype) Error!void {
771
+ return single(self, .SingleMove, args);
809
772
  }
810
773
 
811
- pub fn singlemove(self: Self, ident: ID, m: anytype) Error!void {
812
- return single(self, .SingleMove, ident, m);
774
+ // ident: ID, move: <Move>
775
+ pub fn singleturn(self: Self, args: anytype) Error!void {
776
+ return single(self, .SingleTurn, args);
813
777
  }
814
778
 
815
- pub fn singleturn(self: Self, ident: ID, m: anytype) Error!void {
816
- return single(self, .SingleTurn, ident, m);
817
- }
818
-
819
- fn single(self: Self, arg: ArgType, ident: ID, m: anytype) Error!void {
779
+ // ident: ID, move: <Move>
780
+ fn single(self: Self, arg: ArgType, args: anytype) Error!void {
820
781
  if (!enabled) return;
821
782
 
822
783
  try self.writer.writeAll(&.{
823
784
  @intFromEnum(arg),
824
- @as(u8, @bitCast(ident)),
825
- @intFromEnum(m),
785
+ @as(u8, @bitCast(args[0])),
786
+ @intFromEnum(args[1]),
826
787
  });
827
788
  }
828
789
 
829
- pub fn weather(self: Self, w: anytype, reason: Weather) Error!void {
790
+ // weather: <Weather>, reason: Weather
791
+ pub fn weather(self: Self, args: anytype) Error!void {
830
792
  if (!enabled) return;
831
793
 
832
- assert(!(w == .None and reason == .Upkeep));
794
+ assert(!(args[0] == .None and args[1] == .Upkeep));
833
795
  try self.writer.writeAll(&.{
834
796
  @intFromEnum(ArgType.Weather),
835
- @intFromEnum(w),
836
- @intFromEnum(reason),
797
+ @intFromEnum(args[0]),
798
+ @intFromEnum(@as(Weather, args[1])),
837
799
  });
838
800
  }
839
801
 
840
- pub fn laststill(self: Self) Error!void {
802
+ // -
803
+ pub fn laststill(self: Self, _: anytype) Error!void {
841
804
  if (!enabled) return;
842
805
 
843
806
  try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
844
807
  }
845
808
 
846
- pub fn lastmiss(self: Self) Error!void {
809
+ // -
810
+ pub fn lastmiss(self: Self, _: anytype) Error!void {
847
811
  if (!enabled) return;
848
812
 
849
813
  try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
@@ -874,10 +838,10 @@ pub const ByteStream = struct {
874
838
  try self.stream.writeByte(byte);
875
839
  }
876
840
 
877
- pub fn writeIntNative(self: Writer, comptime T: type, value: T) Error!void {
841
+ pub fn writeInt(self: Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
878
842
  // TODO: rework this to write directly to the buffer?
879
- var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
880
- std.mem.writeIntNative(T, &bytes, value);
843
+ var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined;
844
+ std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(v)), &bytes, v, end);
881
845
  return self.writeAll(&bytes);
882
846
  }
883
847
  };
@@ -986,19 +950,19 @@ pub fn format(
986
950
  if (a[i] == N(gen.Gender.Unknown)) {
987
951
  i += 1;
988
952
  } else {
989
- var gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
953
+ const gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
990
954
  printc(", {s}", .{gender}, a, b, &i, 1, color);
991
955
  }
992
956
  }
993
957
  printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
994
958
  switch (endian) {
995
- .Big => {
959
+ .big => {
996
960
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
997
961
  printc(" {d}", .{hp}, a, b, &i, 2, color);
998
962
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
999
963
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1000
964
  },
1001
- .Little => {
965
+ .little => {
1002
966
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1003
967
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1004
968
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1029,8 +993,8 @@ pub fn format(
1029
993
  },
1030
994
  .Turn => {
1031
995
  const turn = switch (endian) {
1032
- .Big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
1033
- .Little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
996
+ .big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
997
+ .little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
1034
998
  };
1035
999
  printc(" {d}", .{turn}, a, b, &i, 2, color);
1036
1000
  },
@@ -1041,13 +1005,13 @@ pub fn format(
1041
1005
  var id = ID.from(@intCast(a[i]));
1042
1006
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1043
1007
  switch (endian) {
1044
- .Big => {
1008
+ .big => {
1045
1009
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1046
1010
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1047
1011
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1048
1012
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1049
1013
  },
1050
- .Little => {
1014
+ .little => {
1051
1015
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1052
1016
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1053
1017
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1112,7 +1076,13 @@ pub fn format(
1112
1076
  .Activate => {
1113
1077
  const id = ID.from(@intCast(a[i]));
1114
1078
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1115
- printc(" {s}", .{@tagName(@as(Activate, @enumFromInt(a[i])))}, a, b, &i, 1, color);
1079
+ const reason: Activate = @enumFromInt(a[i]);
1080
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
1081
+ if (reason == .SubstituteBlock) {
1082
+ printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
1083
+ } else if (reason == .Magnitude) {
1084
+ printc(" {d}", .{a[i]}, a, b, &i, 1, color);
1085
+ }
1116
1086
  },
1117
1087
  .Start => {
1118
1088
  const id = ID.from(@intCast(a[i]));
@@ -1120,6 +1090,7 @@ pub fn format(
1120
1090
  const reason = a[i];
1121
1091
  printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
1122
1092
  if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
1093
+ // FIXME
1123
1094
  const types = @as(gen1.Types, @bitCast(a[i]));
1124
1095
  const args = .{
1125
1096
  formatter(gen, .Type, @intFromEnum(types.type1)),
@@ -1162,13 +1133,13 @@ pub fn format(
1162
1133
  const id = ID.from(@intCast(a[i]));
1163
1134
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1164
1135
  switch (endian) {
1165
- .Big => {
1136
+ .big => {
1166
1137
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1167
1138
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1168
1139
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1169
1140
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1170
1141
  },
1171
- .Little => {
1142
+ .little => {
1172
1143
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1173
1144
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1174
1145
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1236,14 +1207,11 @@ pub fn expectLog(
1236
1207
  ) !void {
1237
1208
  if (!enabled) return;
1238
1209
 
1239
- const color = color: {
1240
- if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
1241
- break :color true;
1242
- } else if (std.process.hasEnvVarConstant("NO_COLOR")) {
1243
- break :color false;
1244
- } else {
1245
- break :color std.io.getStdErr().supportsAnsiEscapeCodes();
1246
- }
1210
+ const color = if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR"))
1211
+ true
1212
+ else switch (std.io.tty.detectConfig(std.io.getStdErr())) {
1213
+ .escape_codes => true,
1214
+ else => false,
1247
1215
  };
1248
1216
 
1249
1217
  expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
@@ -1275,8 +1243,6 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
1275
1243
  }
1276
1244
  }
1277
1245
 
1278
- const endian = builtin.target.cpu.arch.endian();
1279
-
1280
1246
  fn N(e: anytype) u8 {
1281
1247
  return @intFromEnum(e);
1282
1248
  }
@@ -1284,20 +1250,13 @@ fn N(e: anytype) u8 {
1284
1250
  const p1 = Player.P1;
1285
1251
  const p2 = Player.P2;
1286
1252
 
1287
- const gen1 = struct {
1288
- pub usingnamespace @import("../gen1/data.zig");
1289
- pub const helpers = @import("../gen1/helpers.zig");
1290
- };
1291
-
1292
- const gen2 = struct {
1293
- pub usingnamespace @import("../gen2/data.zig");
1294
- pub const helpers = @import("../gen2/helpers.zig");
1295
- };
1296
-
1297
- var buf: [gen1.LOGS_SIZE]u8 = undefined;
1253
+ var buf: [pkmn.LOGS_SIZE]u8 = undefined;
1298
1254
  var stream: ByteStream = .{ .buffer = &buf };
1299
1255
  var log: FixedLog = .{ .writer = stream.writer() };
1300
1256
 
1257
+ const gen1 = pkmn.gen1;
1258
+ const gen2 = pkmn.gen2;
1259
+
1301
1260
  const M1 = gen1.Move;
1302
1261
  const S1 = gen1.Species;
1303
1262
 
@@ -1332,22 +1291,22 @@ fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
1332
1291
  }
1333
1292
 
1334
1293
  test "|move|" {
1335
- try log.move(p2.ident(4), M1.Thunderbolt, p1.ident(5));
1294
+ try log.move(.{ p2.ident(4), M1.Thunderbolt, p1.ident(5) });
1336
1295
  try expectLog1(
1337
1296
  &.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
1338
1297
  buf[0..5],
1339
1298
  );
1340
1299
  stream.reset();
1341
1300
 
1342
- try log.moveFrom(p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome);
1301
+ try log.move(.{ p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome });
1343
1302
  try expectLog1(
1344
1303
  &.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
1345
1304
  buf[0..6],
1346
1305
  );
1347
1306
  stream.reset();
1348
1307
 
1349
- try log.move(p2.ident(4), M1.SkullBash, .{});
1350
- try log.laststill();
1308
+ try log.move(.{ p2.ident(4), M1.SkullBash, ID{} });
1309
+ try log.laststill(.{});
1351
1310
  try expectLog1(
1352
1311
  &.{
1353
1312
  N(ArgType.Move),
@@ -1361,8 +1320,8 @@ test "|move|" {
1361
1320
  );
1362
1321
  stream.reset();
1363
1322
 
1364
- try log.move(p2.ident(4), M1.Tackle, p1.ident(5));
1365
- try log.lastmiss();
1323
+ try log.move(.{ p2.ident(4), M1.Tackle, p1.ident(5) });
1324
+ try log.lastmiss(.{});
1366
1325
  try expectLog1(
1367
1326
  &.{
1368
1327
  N(ArgType.Move),
@@ -1383,11 +1342,11 @@ test "|switch|" {
1383
1342
  snorlax.hp = 200;
1384
1343
  snorlax.stats.hp = 400;
1385
1344
  snorlax.status = gen1.Status.init(.PAR);
1386
- try log.switched(p2.ident(3), &snorlax);
1345
+ try log.switched(.{ p2.ident(3), &snorlax });
1387
1346
  const par = 0b1000000;
1388
1347
  var expected: []const u8 = switch (endian) {
1389
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1390
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1348
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1349
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1391
1350
  };
1392
1351
  try expectLog1(expected, buf[0..9]);
1393
1352
  stream.reset();
@@ -1395,19 +1354,19 @@ test "|switch|" {
1395
1354
  snorlax.level = 100;
1396
1355
  snorlax.hp = 0;
1397
1356
  snorlax.status = 0;
1398
- try log.switched(p2.ident(3), &snorlax);
1357
+ try log.switched(.{ p2.ident(3), &snorlax });
1399
1358
  expected = switch (endian) {
1400
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1401
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1359
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1360
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1402
1361
  };
1403
1362
  try expectLog1(expected, buf[0..9]);
1404
1363
  stream.reset();
1405
1364
 
1406
1365
  snorlax.hp = 400;
1407
- try log.switched(p2.ident(3), &snorlax);
1366
+ try log.switched(.{ p2.ident(3), &snorlax });
1408
1367
  expected = switch (endian) {
1409
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1410
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1368
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1369
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1411
1370
  };
1412
1371
  try expectLog1(expected, buf[0..9]);
1413
1372
  stream.reset();
@@ -1417,7 +1376,7 @@ test "|switch|" {
1417
1376
  blissey.hp = 200;
1418
1377
  blissey.stats.hp = 400;
1419
1378
  blissey.status = gen2.Status.init(.PAR);
1420
- try log.switched(p2.ident(3), &blissey);
1379
+ try log.switched(.{ p2.ident(3), &blissey });
1421
1380
  expected = &(.{
1422
1381
  N(ArgType.Switch),
1423
1382
  0b1011,
@@ -1425,51 +1384,51 @@ test "|switch|" {
1425
1384
  N(gen2.Gender.Female),
1426
1385
  91,
1427
1386
  } ++ switch (endian) {
1428
- .Big => .{ 0, 200, 1, 144, par },
1429
- .Little => .{ 200, 0, 144, 1, par },
1387
+ .big => .{ 0, 200, 1, 144, par },
1388
+ .little => .{ 200, 0, 144, 1, par },
1430
1389
  });
1431
1390
  try expectLog2(expected, buf[0..10]);
1432
1391
  stream.reset();
1433
1392
  }
1434
1393
 
1435
1394
  test "|cant|" {
1436
- try log.cant(p2.ident(6), .Bound);
1395
+ try log.cant(.{ p2.ident(6), .Bound });
1437
1396
  try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
1438
1397
  stream.reset();
1439
1398
 
1440
- try log.disabled(p1.ident(2), M1.Earthquake);
1399
+ try log.cant(.{ p1.ident(2), .Disable, M1.Earthquake });
1441
1400
  try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
1442
1401
  stream.reset();
1443
1402
  }
1444
1403
 
1445
1404
  test "|faint|" {
1446
- try log.faint(p2.ident(2), false);
1405
+ try log.faint(.{ p2.ident(2), false });
1447
1406
  try expectLog1(&.{ N(ArgType.Faint), 0b1010 }, buf[0..2]);
1448
1407
  stream.reset();
1449
1408
 
1450
- try log.faint(p2.ident(2), true);
1409
+ try log.faint(.{ p2.ident(2), true });
1451
1410
  try expectLog1(&.{ N(ArgType.Faint), 0b1010, N(ArgType.None) }, buf[0..3]);
1452
1411
  stream.reset();
1453
1412
  }
1454
1413
 
1455
1414
  test "|turn|" {
1456
- try log.turn(42);
1457
- var expected = switch (endian) {
1458
- .Big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1459
- .Little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1415
+ try log.turn(.{42});
1416
+ const expected = switch (endian) {
1417
+ .big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1418
+ .little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1460
1419
  };
1461
1420
  try expectLog1(expected, buf[0..4]);
1462
1421
  stream.reset();
1463
1422
  }
1464
1423
 
1465
1424
  test "|win|" {
1466
- try log.win(.P2);
1425
+ try log.win(.{.P2});
1467
1426
  try expectLog1(&.{ N(ArgType.Win), 1, N(ArgType.None) }, buf[0..3]);
1468
1427
  stream.reset();
1469
1428
  }
1470
1429
 
1471
1430
  test "|tie|" {
1472
- try log.tie();
1431
+ try log.tie(.{});
1473
1432
  try expectLog1(&.{ N(ArgType.Tie), N(ArgType.None) }, buf[0..2]);
1474
1433
  stream.reset();
1475
1434
  }
@@ -1478,10 +1437,10 @@ test "|-damage|" {
1478
1437
  var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
1479
1438
  chansey.hp = 612;
1480
1439
  chansey.status = gen1.Status.slp(1);
1481
- try log.damage(p2.ident(2), &chansey, .None);
1440
+ try log.damage(.{ p2.ident(2), &chansey, .None });
1482
1441
  var expected: []const u8 = switch (endian) {
1483
- .Big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1484
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1442
+ .big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1443
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1485
1444
  };
1486
1445
  try expectLog1(expected, buf[0..8]);
1487
1446
  stream.reset();
@@ -1489,19 +1448,19 @@ test "|-damage|" {
1489
1448
  chansey.hp = 100;
1490
1449
  chansey.stats.hp = 256;
1491
1450
  chansey.status = 0;
1492
- try log.damage(p2.ident(2), &chansey, .Confusion);
1451
+ try log.damage(.{ p2.ident(2), &chansey, .Confusion });
1493
1452
  expected = switch (endian) {
1494
- .Big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1495
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1453
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1454
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1496
1455
  };
1497
1456
  try expectLog1(expected, buf[0..8]);
1498
1457
  stream.reset();
1499
1458
 
1500
1459
  chansey.status = gen1.Status.init(.PSN);
1501
- try log.damageOf(p2.ident(2), &chansey, .RecoilOf, p1.ident(1));
1460
+ try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
1502
1461
  expected = switch (endian) {
1503
- .Big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1504
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1462
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1463
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1505
1464
  };
1506
1465
  try expectLog1(expected, buf[0..9]);
1507
1466
  stream.reset();
@@ -1511,10 +1470,10 @@ test "|-heal|" {
1511
1470
  var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
1512
1471
  chansey.hp = 612;
1513
1472
  chansey.status = gen1.Status.slp(1);
1514
- try log.heal(.{ p2.ident(2), &chansey, Heal.None });
1473
+ try log.heal(.{ p2.ident(2), &chansey, .None });
1515
1474
  var expected: []const u8 = switch (endian) {
1516
- .Big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1517
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1475
+ .big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1476
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1518
1477
  };
1519
1478
  try expectLog1(expected, buf[0..8]);
1520
1479
  stream.reset();
@@ -1522,33 +1481,33 @@ test "|-heal|" {
1522
1481
  chansey.hp = 100;
1523
1482
  chansey.stats.hp = 256;
1524
1483
  chansey.status = 0;
1525
- try log.heal(.{ p2.ident(2), &chansey, Heal.Silent });
1484
+ try log.heal(.{ p2.ident(2), &chansey, .Silent });
1526
1485
  expected = switch (endian) {
1527
- .Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1528
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1486
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1487
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1529
1488
  };
1530
1489
  try expectLog1(expected, buf[0..8]);
1531
1490
  stream.reset();
1532
1491
 
1533
- try log.drain(p2.ident(2), &chansey, p1.ident(1));
1492
+ try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
1534
1493
  expected = switch (endian) {
1535
- .Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1536
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1494
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1495
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1537
1496
  };
1538
1497
  try expectLog1(expected, buf[0..9]);
1539
1498
  stream.reset();
1540
1499
  }
1541
1500
 
1542
1501
  test "|-status|" {
1543
- try log.status(p2.ident(6), gen1.Status.init(.BRN), .None);
1502
+ try log.status(.{ p2.ident(6), gen1.Status.init(.BRN), .None });
1544
1503
  try expectLog1(&.{ N(ArgType.Status), 0b1110, 0b10000, N(Status.None) }, buf[0..4]);
1545
1504
  stream.reset();
1546
1505
 
1547
- try log.status(p2.ident(2), gen1.Status.init(.PSN), .Silent);
1506
+ try log.status(.{ p2.ident(2), gen1.Status.init(.PSN), .Silent });
1548
1507
  try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
1549
1508
  stream.reset();
1550
1509
 
1551
- try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR), M1.BodySlam);
1510
+ try log.status(.{ p1.ident(1), gen1.Status.init(.PAR), .From, M1.BodySlam });
1552
1511
  try expectLog1(
1553
1512
  &.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
1554
1513
  buf[0..5],
@@ -1557,11 +1516,11 @@ test "|-status|" {
1557
1516
  }
1558
1517
 
1559
1518
  test "|-curestatus|" {
1560
- try log.curestatus(p2.ident(6), gen1.Status.slp(7), .Message);
1519
+ try log.curestatus(.{ p2.ident(6), gen1.Status.slp(7), .Message });
1561
1520
  try expectLog1(&.{ N(ArgType.CureStatus), 0b1110, 0b111, N(CureStatus.Message) }, buf[0..4]);
1562
1521
  stream.reset();
1563
1522
 
1564
- try log.curestatus(p1.ident(2), gen1.Status.TOX, .Silent);
1523
+ try log.curestatus(.{ p1.ident(2), gen1.Status.TOX, .Silent });
1565
1524
  try expectLog1(&.{
1566
1525
  N(ArgType.CureStatus),
1567
1526
  0b0010,
@@ -1572,174 +1531,191 @@ test "|-curestatus|" {
1572
1531
  }
1573
1532
 
1574
1533
  test "|-boost|" {
1575
- try log.boost(p2.ident(6), .Speed, 2);
1534
+ try log.boost(.{ p2.ident(6), .Speed, 2 });
1576
1535
  try expectLog1(&.{ N(ArgType.Boost), 0b1110, N(Boost.Speed), 8 }, buf[0..4]);
1577
1536
  stream.reset();
1578
1537
 
1579
- try log.boost(p1.ident(2), .Rage, 1);
1538
+ try log.boost(.{ p1.ident(2), .Rage, 1 });
1580
1539
  try expectLog1(&.{ N(ArgType.Boost), 0b0010, N(Boost.Rage), 7 }, buf[0..4]);
1581
1540
  stream.reset();
1582
1541
 
1583
- try log.boost(p2.ident(3), .Defense, -2);
1542
+ try log.boost(.{ p2.ident(3), .Defense, -2 });
1584
1543
  try expectLog1(&.{ N(ArgType.Boost), 0b1011, N(Boost.Defense), 4 }, buf[0..4]);
1585
1544
  stream.reset();
1586
1545
  }
1587
1546
 
1588
1547
  test "|-clearallboost|" {
1589
- try log.clearallboost();
1548
+ try log.clearallboost(.{});
1590
1549
  try expectLog1(&.{N(ArgType.ClearAllBoost)}, buf[0..1]);
1591
1550
  stream.reset();
1592
1551
  }
1593
1552
 
1594
1553
  test "|-fail|" {
1595
- try log.fail(p2.ident(6), .None);
1554
+ try log.fail(.{ p2.ident(6), .None });
1596
1555
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.None) }, buf[0..3]);
1597
1556
  stream.reset();
1598
1557
 
1599
- try log.fail(p2.ident(6), .Sleep);
1558
+ try log.fail(.{ p2.ident(6), .Sleep });
1600
1559
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Sleep) }, buf[0..3]);
1601
1560
  stream.reset();
1602
1561
 
1603
- try log.fail(p2.ident(6), .Substitute);
1562
+ try log.fail(.{ p2.ident(6), .Substitute });
1604
1563
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Substitute) }, buf[0..3]);
1605
1564
  stream.reset();
1606
1565
 
1607
- try log.fail(p2.ident(6), .Weak);
1566
+ try log.fail(.{ p2.ident(6), .Weak });
1608
1567
  try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Weak) }, buf[0..3]);
1609
1568
  stream.reset();
1610
1569
  }
1611
1570
 
1612
1571
  test "|-miss|" {
1613
- try log.miss(p2.ident(4));
1572
+ try log.miss(.{p2.ident(4)});
1614
1573
  try expectLog1(&.{ N(ArgType.Miss), 0b1100 }, buf[0..2]);
1615
1574
  stream.reset();
1616
1575
  }
1617
1576
  test "|-hitcount|" {
1618
- try log.hitcount(p2.ident(1), 5);
1577
+ try log.hitcount(.{ p2.ident(1), 5 });
1619
1578
  try expectLog1(&.{ N(ArgType.HitCount), 0b1001, 5 }, buf[0..3]);
1620
1579
  stream.reset();
1621
1580
  }
1622
1581
 
1623
1582
  test "|-prepare|" {
1624
- try log.prepare(p2.ident(2), M1.Dig);
1583
+ try log.prepare(.{ p2.ident(2), M1.Dig });
1625
1584
  try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
1626
1585
  stream.reset();
1627
1586
  }
1628
1587
 
1629
1588
  test "|-mustrecharge|" {
1630
- try log.mustrecharge(p1.ident(6));
1589
+ try log.mustrecharge(.{p1.ident(6)});
1631
1590
  try expectLog1(&.{ N(ArgType.MustRecharge), 0b0110 }, buf[0..2]);
1632
1591
  stream.reset();
1633
1592
  }
1634
1593
 
1635
1594
  test "|-activate|" {
1636
- try log.activate(p1.ident(2), .Struggle);
1595
+ try log.activate(.{ p1.ident(2), .Struggle });
1637
1596
  try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Struggle) }, buf[0..3]);
1638
1597
  stream.reset();
1639
1598
 
1640
- try log.activate(p2.ident(4), .Mist);
1599
+ try log.activate(.{ p2.ident(4), .Mist });
1641
1600
  try expectLog1(&.{ N(ArgType.Activate), 0b1100, N(Activate.Mist) }, buf[0..3]);
1642
1601
  stream.reset();
1643
1602
 
1644
- try log.activate(p2.ident(6), .Substitute);
1603
+ try log.activate(.{ p2.ident(6), .Substitute });
1645
1604
  try expectLog1(&.{ N(ArgType.Activate), 0b1110, N(Activate.Substitute) }, buf[0..3]);
1646
1605
  stream.reset();
1647
1606
 
1648
- try log.activate(p1.ident(2), .Splash);
1607
+ try log.activate(.{ p1.ident(2), .Splash });
1649
1608
  try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
1650
1609
  stream.reset();
1651
1610
 
1652
- // TODO activateMove
1611
+ try log.activate(.{ p1.ident(4), .SubstituteBlock, M2.Spite });
1612
+ try expectLog1(&.{
1613
+ N(ArgType.Activate),
1614
+ 0b0100,
1615
+ N(Activate.SubstituteBlock),
1616
+ N(M2.Spite),
1617
+ }, buf[0..4]);
1618
+ stream.reset();
1653
1619
 
1654
- try log.magnitude(p1.ident(3), 5);
1620
+ try log.activate(.{ p1.ident(3), .Magnitude, 5 });
1655
1621
  try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
1656
1622
  stream.reset();
1657
1623
  }
1658
1624
 
1659
1625
  test "|-fieldactivate|" {
1660
- try log.fieldactivate();
1626
+ try log.fieldactivate(.{});
1661
1627
  try expectLog1(&.{N(ArgType.FieldActivate)}, buf[0..1]);
1662
1628
  stream.reset();
1663
1629
  }
1664
1630
 
1665
1631
  test "|-start|" {
1666
- try log.start(p2.ident(6), .Bide);
1632
+ try log.start(.{ p2.ident(6), .Bide });
1667
1633
  try expectLog1(&.{ N(ArgType.Start), 0b1110, N(Start.Bide) }, buf[0..3]);
1668
1634
  stream.reset();
1669
1635
 
1670
- try log.start(p1.ident(2), .ConfusionSilent);
1636
+ try log.start(.{ p1.ident(2), .ConfusionSilent });
1671
1637
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.ConfusionSilent) }, buf[0..3]);
1672
1638
  stream.reset();
1673
1639
 
1674
- try log.typechange(p2.ident(6), gen1.Types{ .type1 = .Fire, .type2 = .Fire }, p2.ident(5));
1640
+ try log.start(.{
1641
+ p2.ident(6),
1642
+ .TypeChange,
1643
+ gen1.Types{ .type1 = .Fire, .type2 = .Fire },
1644
+ p2.ident(5),
1645
+ });
1675
1646
  try expectLog1(
1676
1647
  &.{ N(ArgType.Start), 0b1110, N(Start.TypeChange), 0b1000_1000, 0b1101 },
1677
1648
  buf[0..5],
1678
1649
  );
1679
1650
  stream.reset();
1680
1651
 
1681
- try log.typechange(p1.ident(2), gen1.Types{ .type1 = .Bug, .type2 = .Poison }, p2.ident(4));
1652
+ try log.start(.{
1653
+ p1.ident(2),
1654
+ .TypeChange,
1655
+ gen1.Types{ .type1 = .Bug, .type2 = .Poison },
1656
+ p2.ident(4),
1657
+ });
1682
1658
  try expectLog1(
1683
1659
  &.{ N(ArgType.Start), 0b0010, N(Start.TypeChange), 0b0011_0110, 0b1100 },
1684
1660
  buf[0..5],
1685
1661
  );
1686
1662
  stream.reset();
1687
1663
 
1688
- try log.startEffect(p1.ident(2), .Disable, M1.Surf);
1664
+ try log.start(.{ p1.ident(2), .Disable, M1.Surf });
1689
1665
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
1690
1666
  stream.reset();
1691
1667
 
1692
- try log.startEffect(p1.ident(2), .Mimic, M1.Surf);
1668
+ try log.start(.{ p1.ident(2), .Mimic, M1.Surf });
1693
1669
  try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
1694
1670
  stream.reset();
1695
1671
  }
1696
1672
 
1697
1673
  test "|-end|" {
1698
- try log.end(p2.ident(6), .Bide);
1674
+ try log.end(.{ p2.ident(6), .Bide });
1699
1675
  try expectLog1(&.{ N(ArgType.End), 0b1110, N(End.Bide) }, buf[0..3]);
1700
1676
  stream.reset();
1701
1677
 
1702
- try log.end(p1.ident(2), .ConfusionSilent);
1678
+ try log.end(.{ p1.ident(2), .ConfusionSilent });
1703
1679
  try expectLog1(&.{ N(ArgType.End), 0b0010, N(End.ConfusionSilent) }, buf[0..3]);
1704
1680
  stream.reset();
1705
1681
  }
1706
1682
 
1707
1683
  test "|-ohko|" {
1708
- try log.ohko();
1684
+ try log.ohko(.{});
1709
1685
  try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
1710
1686
  stream.reset();
1711
1687
  }
1712
1688
 
1713
1689
  test "|-crit|" {
1714
- try log.crit(p2.ident(5));
1690
+ try log.crit(.{p2.ident(5)});
1715
1691
  try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
1716
1692
  stream.reset();
1717
1693
  }
1718
1694
 
1719
1695
  test "|-supereffective|" {
1720
- try log.supereffective(p1.ident(1));
1696
+ try log.supereffective(.{p1.ident(1)});
1721
1697
  try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
1722
1698
  stream.reset();
1723
1699
  }
1724
1700
 
1725
1701
  test "|-resisted|" {
1726
- try log.resisted(p2.ident(2));
1702
+ try log.resisted(.{p2.ident(2)});
1727
1703
  try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
1728
1704
  stream.reset();
1729
1705
  }
1730
1706
 
1731
1707
  test "|-immune|" {
1732
- try log.immune(p1.ident(3), .None);
1708
+ try log.immune(.{ p1.ident(3), .None });
1733
1709
  try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
1734
1710
  stream.reset();
1735
1711
 
1736
- try log.immune(p2.ident(2), .OHKO);
1712
+ try log.immune(.{ p2.ident(2), .OHKO });
1737
1713
  try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
1738
1714
  stream.reset();
1739
1715
  }
1740
1716
 
1741
1717
  test "|-transform|" {
1742
- try log.transform(p2.ident(4), p1.ident(5));
1718
+ try log.transform(.{ p2.ident(4), p1.ident(5) });
1743
1719
  try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
1744
1720
  stream.reset();
1745
1721
  }
@@ -1750,7 +1726,7 @@ test "|drag|" {
1750
1726
  blissey.hp = 200;
1751
1727
  blissey.stats.hp = 400;
1752
1728
  blissey.status = gen2.Status.init(.PAR);
1753
- try log.drag(p2.ident(3), &blissey);
1729
+ try log.drag(.{ p2.ident(3), &blissey });
1754
1730
  const par = 0b1000000;
1755
1731
  const expected = &(.{
1756
1732
  N(ArgType.Drag),
@@ -1759,31 +1735,31 @@ test "|drag|" {
1759
1735
  N(gen2.Gender.Female),
1760
1736
  91,
1761
1737
  } ++ switch (endian) {
1762
- .Big => .{ 0, 200, 1, 144, par },
1763
- .Little => .{ 200, 0, 144, 1, par },
1738
+ .big => .{ 0, 200, 1, 144, par },
1739
+ .little => .{ 200, 0, 144, 1, par },
1764
1740
  });
1765
1741
  try expectLog2(expected, buf[0..10]);
1766
1742
  stream.reset();
1767
1743
  }
1768
1744
 
1769
1745
  test "|-item|" {
1770
- try log.item(p2.ident(2), I2.GoldBerry, p1.ident(4));
1746
+ try log.item(.{ p2.ident(2), I2.GoldBerry, p1.ident(4) });
1771
1747
  try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
1772
1748
  stream.reset();
1773
1749
  }
1774
1750
 
1775
1751
  test "|-enditem|" {
1776
- try log.enditem(p1.ident(1), I2.BerserkGene, .None);
1752
+ try log.enditem(.{ p1.ident(1), I2.BerserkGene, .None });
1777
1753
  try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
1778
1754
  stream.reset();
1779
1755
 
1780
- try log.enditem(p2.ident(4), I2.PRZCureBerry, .Eat);
1756
+ try log.enditem(.{ p2.ident(4), I2.PRZCureBerry, .Eat });
1781
1757
  try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
1782
1758
  stream.reset();
1783
1759
  }
1784
1760
 
1785
1761
  test "|-cureteam|" {
1786
- try log.cureteam(p2.ident(5));
1762
+ try log.cureteam(.{p2.ident(5)});
1787
1763
  try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
1788
1764
  stream.reset();
1789
1765
  }
@@ -1791,43 +1767,43 @@ test "|-cureteam|" {
1791
1767
  test "|-sethp|" {
1792
1768
  var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
1793
1769
  blissey.hp = 612;
1794
- try log.sethp(p2.ident(2), &blissey, .Silent);
1795
- var expected: []const u8 = switch (endian) {
1796
- .Big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1797
- .Little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1770
+ try log.sethp(.{ p2.ident(2), &blissey, .Silent });
1771
+ const expected: []const u8 = switch (endian) {
1772
+ .big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1773
+ .little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1798
1774
  };
1799
1775
  try expectLog2(expected, buf[0..8]);
1800
1776
  stream.reset();
1801
1777
  }
1802
1778
 
1803
1779
  test "|-setboost|" {
1804
- try log.setboost(p2.ident(6), 6);
1780
+ try log.setboost(.{ p2.ident(6), 6 });
1805
1781
  try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
1806
1782
  stream.reset();
1807
1783
 
1808
- try log.setboost(p2.ident(3), 2);
1784
+ try log.setboost(.{ p2.ident(3), 2 });
1809
1785
  try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
1810
1786
  stream.reset();
1811
1787
  }
1812
1788
 
1813
1789
  test "|-copyboost|" {
1814
- try log.copyboost(p2.ident(3), p1.ident(6));
1790
+ try log.copyboost(.{ p2.ident(3), p1.ident(6) });
1815
1791
  try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
1816
1792
  stream.reset();
1817
1793
  }
1818
1794
 
1819
1795
  test "|-sidestart|" {
1820
- try log.sidestart(.P2, .Reflect);
1796
+ try log.sidestart(.{ .P2, .Reflect });
1821
1797
  try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
1822
1798
  stream.reset();
1823
1799
  }
1824
1800
 
1825
1801
  test "|-sideend|" {
1826
- try log.sideend(.P2, .LightScreen);
1802
+ try log.sideend(.{ .P2, .LightScreen });
1827
1803
  try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
1828
1804
  stream.reset();
1829
1805
 
1830
- try log.spikesend(p1.ident(3));
1806
+ try log.sideend(.{ .P1, .Spikes, p1.ident(3) });
1831
1807
  try expectLog2(&.{
1832
1808
  N(ArgType.SideEnd),
1833
1809
  0,
@@ -1838,23 +1814,23 @@ test "|-sideend|" {
1838
1814
  }
1839
1815
 
1840
1816
  test "|-singlemove|" {
1841
- try log.singlemove(p2.ident(2), M2.DestinyBond);
1817
+ try log.singlemove(.{ p2.ident(2), M2.DestinyBond });
1842
1818
  try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
1843
1819
  stream.reset();
1844
1820
  }
1845
1821
 
1846
1822
  test "|-singleturn|" {
1847
- try log.singleturn(p1.ident(3), M2.Protect);
1823
+ try log.singleturn(.{ p1.ident(3), M2.Protect });
1848
1824
  try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
1849
1825
  stream.reset();
1850
1826
  }
1851
1827
 
1852
1828
  test "|-weather|" {
1853
- try log.weather(W2.Rain, .Upkeep);
1829
+ try log.weather(.{ W2.Rain, .Upkeep });
1854
1830
  try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
1855
1831
  stream.reset();
1856
1832
 
1857
- try log.weather(W2.None, .None);
1833
+ try log.weather(.{ W2.None, .None });
1858
1834
  try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
1859
1835
  stream.reset();
1860
1836
  }