@pkmn/engine 0.1.0-dev.dc33f678 → 0.1.0-dev.deda8593

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