@pkmn/engine 0.1.0-dev.dfd46bbb → 0.1.0-dev.e0e37c1b

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