@pkmn/engine 0.1.0-dev.21e728d9 → 0.1.0-dev.29e0e9e1

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