@pkmn/engine 0.1.0-dev.21e728d9 → 0.1.0-dev.26a79a0e

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