@pkmn/engine 0.1.0-dev.1220fbc5 → 0.1.0-dev.12e7292c

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