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

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