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

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