@pkmn/engine 0.1.0-dev.979a393a → 0.1.0-dev.a324c50f

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 (41) hide show
  1. package/README.md +32 -29
  2. package/build/pkg/addon.d.ts +7 -0
  3. package/build/pkg/addon.js +112 -0
  4. package/build/pkg/addon.js.map +1 -0
  5. package/build/pkg/data/layout.json +25 -3
  6. package/build/pkg/gen1.d.ts +5 -4
  7. package/build/pkg/gen1.js +47 -31
  8. package/build/pkg/gen1.js.map +1 -1
  9. package/build/pkg/index.d.ts +15 -12
  10. package/build/pkg/index.js.map +1 -1
  11. package/build/pkg/protocol.d.ts +4 -2
  12. package/build/pkg/protocol.js +4 -2
  13. package/build/pkg/protocol.js.map +1 -1
  14. package/build/test/display.js +31 -13
  15. package/build/test/display.js.map +1 -1
  16. package/build.zig +49 -39
  17. package/package.json +18 -14
  18. package/src/bin/install-pkmn-engine +11 -6
  19. package/src/bin/pkmn-debug +29 -6
  20. package/src/lib/binding/node.zig +46 -141
  21. package/src/lib/binding/wasm.zig +6 -4
  22. package/src/lib/common/data.zig +11 -11
  23. package/src/lib/common/debug.zig +21 -11
  24. package/src/lib/common/options.zig +12 -3
  25. package/src/lib/common/protocol.zig +239 -178
  26. package/src/lib/common/rng.zig +10 -10
  27. package/src/lib/gen1/README.md +111 -81
  28. package/src/lib/gen1/data/moves.zig +10 -10
  29. package/src/lib/gen1/data/species.zig +2 -2
  30. package/src/lib/gen1/data/types.zig +3 -3
  31. package/src/lib/gen1/data.zig +64 -43
  32. package/src/lib/gen1/helpers.zig +439 -32
  33. package/src/lib/gen1/mechanics.zig +987 -612
  34. package/src/lib/gen2/data/items.zig +3 -3
  35. package/src/lib/gen2/data/moves.zig +1 -1
  36. package/src/lib/gen2/data/species.zig +1 -1
  37. package/src/lib/gen2/data/types.zig +3 -3
  38. package/src/lib/gen2/data.zig +37 -26
  39. package/src/lib/gen2/helpers.zig +9 -11
  40. package/src/lib/gen2/mechanics.zig +5 -4
  41. package/src/lib/pkmn.zig +68 -9
@@ -7,7 +7,7 @@ const options = @import("./options.zig");
7
7
  const assert = std.debug.assert;
8
8
  const print = std.debug.print;
9
9
 
10
- const trace = options.trace;
10
+ const enabled = options.log;
11
11
 
12
12
  const Player = data.Player;
13
13
  const ID = data.ID;
@@ -219,8 +219,12 @@ pub const Immune = enum(u8) {
219
219
  OHKO,
220
220
  };
221
221
 
222
+ /// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
223
+ /// Ignores anything sent to it, though protocol logging should additionally be turned off
224
+ /// entirely with `options.log`.
222
225
  pub const NULL = Log(@TypeOf(std.io.null_writer)){ .writer = std.io.null_writer };
223
226
 
227
+ /// Logs protocol information to its `Writer` during a battle update when `options.log` is enabled.
224
228
  pub fn Log(comptime Writer: type) type {
225
229
  return struct {
226
230
  const Self = @This();
@@ -230,91 +234,100 @@ pub fn Log(comptime Writer: type) type {
230
234
  pub const Error = Writer.Error;
231
235
 
232
236
  pub fn move(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
233
- if (!trace) return;
237
+ if (!enabled) return;
238
+
234
239
  assert(m != .None);
235
240
  try self.writer.writeAll(&.{
236
- @enumToInt(ArgType.Move),
237
- @bitCast(u8, source),
238
- @enumToInt(m),
239
- @bitCast(u8, target),
241
+ @intFromEnum(ArgType.Move),
242
+ @as(u8, @bitCast(source)),
243
+ @intFromEnum(m),
244
+ @as(u8, @bitCast(target)),
240
245
  });
241
- const none = &[_]u8{@enumToInt(Move.None)};
246
+ const none = &[_]u8{@intFromEnum(Move.None)};
242
247
  try self.writer.writeAll(switch (@typeInfo(@TypeOf(from))) {
243
248
  .Null => none,
244
249
  .Optional => if (from) |f| blk: {
245
- assert(@enumToInt(f) != 0);
246
- break :blk &[_]u8{ @enumToInt(Move.From), @enumToInt(f) };
250
+ assert(@intFromEnum(f) != 0);
251
+ break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(f) };
247
252
  } else none,
248
253
  else => blk: {
249
- assert(@enumToInt(from) != 0);
250
- break :blk &[_]u8{ @enumToInt(Move.From), @enumToInt(from) };
254
+ assert(@intFromEnum(from) != 0);
255
+ break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(from) };
251
256
  },
252
257
  });
253
258
  }
254
259
 
255
260
  pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void {
256
- if (!trace) return;
257
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Switch), @bitCast(u8, ident) });
258
- try self.writer.writeAll(&.{ @enumToInt(pokemon.species), pokemon.level });
261
+ if (!enabled) return;
262
+
263
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Switch), @as(u8, @bitCast(ident)) });
264
+ try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level });
259
265
  try self.writer.writeIntNative(u16, pokemon.hp);
260
266
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
261
267
  try self.writer.writeAll(&.{pokemon.status});
262
268
  }
263
269
 
264
270
  pub fn cant(self: Self, ident: ID, reason: Cant) Error!void {
265
- if (!trace) return;
271
+ if (!enabled) return;
272
+
266
273
  assert(reason != .Disable);
267
274
  try self.writer.writeAll(&.{
268
- @enumToInt(ArgType.Cant),
269
- @bitCast(u8, ident),
270
- @enumToInt(reason),
275
+ @intFromEnum(ArgType.Cant),
276
+ @as(u8, @bitCast(ident)),
277
+ @intFromEnum(reason),
271
278
  });
272
279
  }
273
280
 
274
281
  pub fn disabled(self: Self, ident: ID, m: anytype) Error!void {
275
- if (!trace) return;
282
+ if (!enabled) return;
283
+
276
284
  try self.writer.writeAll(&.{
277
- @enumToInt(ArgType.Cant),
278
- @bitCast(u8, ident),
279
- @enumToInt(Cant.Disable),
280
- @enumToInt(m),
285
+ @intFromEnum(ArgType.Cant),
286
+ @as(u8, @bitCast(ident)),
287
+ @intFromEnum(Cant.Disable),
288
+ @intFromEnum(m),
281
289
  });
282
290
  }
283
291
 
284
292
  pub fn faint(self: Self, ident: ID, done: bool) Error!void {
285
- if (!trace) return;
286
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Faint), @bitCast(u8, ident) });
287
- if (done) try self.writer.writeByte(@enumToInt(ArgType.None));
293
+ if (!enabled) return;
294
+
295
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) });
296
+ if (done) try self.writer.writeByte(@intFromEnum(ArgType.None));
288
297
  }
289
298
 
290
299
  pub fn turn(self: Self, num: u16) Error!void {
291
- if (!trace) return;
292
- try self.writer.writeByte(@enumToInt(ArgType.Turn));
300
+ if (!enabled) return;
301
+
302
+ try self.writer.writeByte(@intFromEnum(ArgType.Turn));
293
303
  try self.writer.writeIntNative(u16, num);
294
- try self.writer.writeByte(@enumToInt(ArgType.None));
304
+ try self.writer.writeByte(@intFromEnum(ArgType.None));
295
305
  }
296
306
 
297
307
  pub fn win(self: Self, player: Player) Error!void {
298
- if (!trace) return;
308
+ if (!enabled) return;
309
+
299
310
  try self.writer.writeAll(&.{
300
- @enumToInt(ArgType.Win),
301
- @enumToInt(player),
302
- @enumToInt(ArgType.None),
311
+ @intFromEnum(ArgType.Win),
312
+ @intFromEnum(player),
313
+ @intFromEnum(ArgType.None),
303
314
  });
304
315
  }
305
316
 
306
317
  pub fn tie(self: Self) Error!void {
307
- if (!trace) return;
308
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Tie), @enumToInt(ArgType.None) });
318
+ if (!enabled) return;
319
+
320
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
309
321
  }
310
322
 
311
323
  pub fn damage(self: Self, ident: ID, pokemon: anytype, reason: Damage) Error!void {
312
- if (!trace) return;
313
- assert(@enumToInt(reason) <= @enumToInt(Damage.LeechSeed));
314
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Damage), @bitCast(u8, ident) });
324
+ if (!enabled) return;
325
+
326
+ assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed));
327
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
315
328
  try self.writer.writeIntNative(u16, pokemon.hp);
316
329
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
317
- try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
330
+ try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
318
331
  }
319
332
 
320
333
  pub fn damageOf(
@@ -324,227 +337,271 @@ pub fn Log(comptime Writer: type) type {
324
337
  reason: Damage,
325
338
  source: ID,
326
339
  ) Error!void {
327
- if (!trace) return;
328
- assert(@enumToInt(reason) == @enumToInt(Damage.RecoilOf));
329
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Damage), @bitCast(u8, ident) });
340
+ if (!enabled) return;
341
+
342
+ assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf));
343
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
330
344
  try self.writer.writeIntNative(u16, pokemon.hp);
331
345
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
332
346
  try self.writer.writeAll(&.{
333
347
  pokemon.status,
334
- @enumToInt(reason),
335
- @bitCast(u8, source),
348
+ @intFromEnum(reason),
349
+ @as(u8, @bitCast(source)),
336
350
  });
337
351
  }
338
352
 
339
353
  pub fn heal(self: Self, ident: ID, pokemon: anytype, reason: Heal) Error!void {
340
- if (!trace) return;
354
+ if (!enabled) return;
355
+
341
356
  assert(reason != .Drain);
342
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Heal), @bitCast(u8, ident) });
357
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(ident)) });
343
358
  try self.writer.writeIntNative(u16, pokemon.hp);
344
359
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
345
- try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
360
+ try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
346
361
  }
347
362
 
348
363
  pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
349
- if (!trace) return;
350
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Heal), @bitCast(u8, source) });
364
+ if (!enabled) return;
365
+
366
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
351
367
  try self.writer.writeIntNative(u16, pokemon.hp);
352
368
  try self.writer.writeIntNative(u16, pokemon.stats.hp);
353
369
  try self.writer.writeAll(&.{
354
370
  pokemon.status,
355
- @enumToInt(Heal.Drain),
356
- @bitCast(u8, target),
371
+ @intFromEnum(Heal.Drain),
372
+ @as(u8, @bitCast(target)),
357
373
  });
358
374
  }
359
375
 
360
376
  pub fn status(self: Self, ident: ID, value: u8, reason: Status) Error!void {
361
- if (!trace) return;
377
+ if (!enabled) return;
378
+
362
379
  assert(reason != .From);
363
380
  try self.writer.writeAll(&.{
364
- @enumToInt(ArgType.Status),
365
- @bitCast(u8, ident),
381
+ @intFromEnum(ArgType.Status),
382
+ @as(u8, @bitCast(ident)),
366
383
  value,
367
- @enumToInt(reason),
384
+ @intFromEnum(reason),
368
385
  });
369
386
  }
370
387
 
371
388
  pub fn statusFrom(self: Self, ident: ID, value: u8, m: anytype) Error!void {
372
- if (!trace) return;
389
+ if (!enabled) return;
390
+
373
391
  try self.writer.writeAll(&.{
374
- @enumToInt(ArgType.Status),
375
- @bitCast(u8, ident),
392
+ @intFromEnum(ArgType.Status),
393
+ @as(u8, @bitCast(ident)),
376
394
  value,
377
- @enumToInt(Status.From),
378
- @enumToInt(m),
395
+ @intFromEnum(Status.From),
396
+ @intFromEnum(m),
379
397
  });
380
398
  }
381
399
 
382
400
  pub fn curestatus(self: Self, ident: ID, value: u8, reason: CureStatus) Error!void {
383
- if (!trace) return;
401
+ if (!enabled) return;
402
+
384
403
  try self.writer.writeAll(&.{
385
- @enumToInt(ArgType.CureStatus),
386
- @bitCast(u8, ident),
404
+ @intFromEnum(ArgType.CureStatus),
405
+ @as(u8, @bitCast(ident)),
387
406
  value,
388
- @enumToInt(reason),
407
+ @intFromEnum(reason),
389
408
  });
390
409
  }
391
410
 
392
411
  pub fn boost(self: Self, ident: ID, reason: Boost, num: i8) Error!void {
393
- if (!trace) return;
412
+ if (!enabled) return;
413
+
394
414
  assert(num != 0 and (reason != .Rage or num > 0));
395
415
  try self.writer.writeAll(&.{
396
- @enumToInt(ArgType.Boost),
397
- @bitCast(u8, ident),
398
- @enumToInt(reason),
399
- @intCast(u8, num + 6),
416
+ @intFromEnum(ArgType.Boost),
417
+ @as(u8, @bitCast(ident)),
418
+ @intFromEnum(reason),
419
+ @as(u8, @intCast(num + 6)),
400
420
  });
401
421
  }
402
422
 
403
423
  pub fn clearallboost(self: Self) Error!void {
404
- if (!trace) return;
405
- try self.writer.writeAll(&.{@enumToInt(ArgType.ClearAllBoost)});
424
+ if (!enabled) return;
425
+
426
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
406
427
  }
407
428
 
408
429
  pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
409
- if (!trace) return;
430
+ if (!enabled) return;
431
+
410
432
  try self.writer.writeAll(&.{
411
- @enumToInt(ArgType.Fail),
412
- @bitCast(u8, ident),
413
- @enumToInt(reason),
433
+ @intFromEnum(ArgType.Fail),
434
+ @as(u8, @bitCast(ident)),
435
+ @intFromEnum(reason),
414
436
  });
415
437
  }
416
438
 
417
439
  pub fn miss(self: Self, source: ID) Error!void {
418
- if (!trace) return;
419
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Miss), @bitCast(u8, source) });
440
+ if (!enabled) return;
441
+
442
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) });
420
443
  }
421
444
 
422
445
  pub fn hitcount(self: Self, ident: ID, num: u8) Error!void {
423
- if (!trace) return;
424
- try self.writer.writeAll(&.{ @enumToInt(ArgType.HitCount), @bitCast(u8, ident), num });
446
+ if (!enabled) return;
447
+
448
+ try self.writer.writeAll(&.{
449
+ @intFromEnum(ArgType.HitCount),
450
+ @as(u8, @bitCast(ident)),
451
+ num,
452
+ });
425
453
  }
426
454
 
427
455
  pub fn prepare(self: Self, source: ID, m: anytype) Error!void {
428
- if (!trace) return;
456
+ if (!enabled) return;
457
+
429
458
  try self.writer.writeAll(&.{
430
- @enumToInt(ArgType.Prepare),
431
- @bitCast(u8, source),
432
- @enumToInt(m),
459
+ @intFromEnum(ArgType.Prepare),
460
+ @as(u8, @bitCast(source)),
461
+ @intFromEnum(m),
433
462
  });
434
463
  }
435
464
 
436
465
  pub fn mustrecharge(self: Self, ident: ID) Error!void {
437
- if (!trace) return;
438
- try self.writer.writeAll(&.{ @enumToInt(ArgType.MustRecharge), @bitCast(u8, ident) });
466
+ if (!enabled) return;
467
+
468
+ try self.writer.writeAll(&.{
469
+ @intFromEnum(ArgType.MustRecharge),
470
+ @as(u8, @bitCast(ident)),
471
+ });
439
472
  }
440
473
 
441
474
  pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
442
- if (!trace) return;
475
+ if (!enabled) return;
476
+
443
477
  try self.writer.writeAll(&.{
444
- @enumToInt(ArgType.Activate),
445
- @bitCast(u8, ident),
446
- @enumToInt(reason),
478
+ @intFromEnum(ArgType.Activate),
479
+ @as(u8, @bitCast(ident)),
480
+ @intFromEnum(reason),
447
481
  });
448
482
  }
449
483
 
450
484
  pub fn fieldactivate(self: Self) Error!void {
451
- if (!trace) return;
452
- try self.writer.writeAll(&.{@enumToInt(ArgType.FieldActivate)});
485
+ if (!enabled) return;
486
+
487
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
453
488
  }
454
489
 
455
490
  pub fn start(self: Self, ident: ID, reason: Start) Error!void {
456
- if (!trace) return;
457
- assert(@enumToInt(reason) < @enumToInt(Start.TypeChange));
491
+ if (!enabled) return;
492
+
493
+ assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
458
494
  try self.writer.writeAll(&.{
459
- @enumToInt(ArgType.Start),
460
- @bitCast(u8, ident),
461
- @enumToInt(reason),
495
+ @intFromEnum(ArgType.Start),
496
+ @as(u8, @bitCast(ident)),
497
+ @intFromEnum(reason),
462
498
  });
463
499
  }
464
500
 
465
501
  pub fn typechange(self: Self, source: ID, types: anytype, target: ID) Error!void {
466
- if (!trace) return;
502
+ if (!enabled) return;
503
+
467
504
  try self.writer.writeAll(&.{
468
- @enumToInt(ArgType.Start),
469
- @bitCast(u8, source),
470
- @enumToInt(Start.TypeChange),
471
- @bitCast(u8, types),
472
- @bitCast(u8, target),
505
+ @intFromEnum(ArgType.Start),
506
+ @as(u8, @bitCast(source)),
507
+ @intFromEnum(Start.TypeChange),
508
+ @as(u8, @bitCast(types)),
509
+ @as(u8, @bitCast(target)),
473
510
  });
474
511
  }
475
512
 
476
513
  pub fn startEffect(self: Self, ident: ID, reason: Start, m: anytype) Error!void {
477
- if (!trace) return;
478
- assert(@enumToInt(reason) > @enumToInt(Start.TypeChange));
514
+ if (!enabled) return;
515
+
516
+ assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
479
517
  try self.writer.writeAll(&.{
480
- @enumToInt(ArgType.Start),
481
- @bitCast(u8, ident),
482
- @enumToInt(reason),
483
- @enumToInt(m),
518
+ @intFromEnum(ArgType.Start),
519
+ @as(u8, @bitCast(ident)),
520
+ @intFromEnum(reason),
521
+ @intFromEnum(m),
484
522
  });
485
523
  }
486
524
 
487
525
  pub fn end(self: Self, ident: ID, reason: End) Error!void {
488
- if (!trace) return;
526
+ if (!enabled) return;
527
+
489
528
  try self.writer.writeAll(&.{
490
- @enumToInt(ArgType.End),
491
- @bitCast(u8, ident),
492
- @enumToInt(reason),
529
+ @intFromEnum(ArgType.End),
530
+ @as(u8, @bitCast(ident)),
531
+ @intFromEnum(reason),
493
532
  });
494
533
  }
495
534
 
496
535
  pub fn ohko(self: Self) Error!void {
497
- if (!trace) return;
498
- try self.writer.writeAll(&.{@enumToInt(ArgType.OHKO)});
536
+ if (!enabled) return;
537
+
538
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
499
539
  }
500
540
 
501
541
  pub fn crit(self: Self, ident: ID) Error!void {
502
- if (!trace) return;
503
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Crit), @bitCast(u8, ident) });
542
+ if (!enabled) return;
543
+
544
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) });
504
545
  }
505
546
 
506
547
  pub fn supereffective(self: Self, ident: ID) Error!void {
507
- if (!trace) return;
508
- try self.writer.writeAll(&.{ @enumToInt(ArgType.SuperEffective), @bitCast(u8, ident) });
548
+ if (!enabled) return;
549
+
550
+ try self.writer.writeAll(&.{
551
+ @intFromEnum(ArgType.SuperEffective),
552
+ @as(u8, @bitCast(ident)),
553
+ });
509
554
  }
510
555
 
511
556
  pub fn resisted(self: Self, ident: ID) Error!void {
512
- if (!trace) return;
513
- try self.writer.writeAll(&.{ @enumToInt(ArgType.Resisted), @bitCast(u8, ident) });
557
+ if (!enabled) return;
558
+
559
+ try self.writer.writeAll(&.{
560
+ @intFromEnum(ArgType.Resisted),
561
+ @as(u8, @bitCast(ident)),
562
+ });
514
563
  }
515
564
 
516
565
  pub fn immune(self: Self, ident: ID, reason: Immune) Error!void {
517
- if (!trace) return;
566
+ if (!enabled) return;
567
+
518
568
  try self.writer.writeAll(&.{
519
- @enumToInt(ArgType.Immune),
520
- @bitCast(u8, ident),
521
- @enumToInt(reason),
569
+ @intFromEnum(ArgType.Immune),
570
+ @as(u8, @bitCast(ident)),
571
+ @intFromEnum(reason),
522
572
  });
523
573
  }
524
574
 
525
575
  pub fn transform(self: Self, source: ID, target: ID) Error!void {
526
- if (!trace) return;
576
+ if (!enabled) return;
577
+
527
578
  try self.writer.writeAll(&.{
528
- @enumToInt(ArgType.Transform),
529
- @bitCast(u8, source),
530
- @bitCast(u8, target),
579
+ @intFromEnum(ArgType.Transform),
580
+ @as(u8, @bitCast(source)),
581
+ @as(u8, @bitCast(target)),
531
582
  });
532
583
  }
533
584
 
534
585
  pub fn laststill(self: Self) Error!void {
535
- if (!trace) return;
536
- try self.writer.writeAll(&.{@enumToInt(ArgType.LastStill)});
586
+ if (!enabled) return;
587
+
588
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
537
589
  }
538
590
 
539
591
  pub fn lastmiss(self: Self) Error!void {
540
- if (!trace) return;
541
- try self.writer.writeAll(&.{@enumToInt(ArgType.LastMiss)});
592
+ if (!enabled) return;
593
+
594
+ try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
542
595
  }
543
596
  };
544
597
  }
545
598
 
599
+ /// `Log` type backed by the optimized `ByteStream.Writer`.
546
600
  pub const FixedLog = Log(ByteStream.Writer);
547
601
 
602
+ /// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
603
+ /// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
604
+ /// should not be used for general purpose writing.
548
605
  pub const ByteStream = struct {
549
606
  buffer: []u8,
550
607
  pos: usize = 0,
@@ -593,7 +650,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
593
650
 
594
651
  var i: usize = 0;
595
652
  while (i < a.len) {
596
- const arg = @intToEnum(ArgType, a[i]);
653
+ const arg: ArgType = @enumFromInt(a[i]);
597
654
  const name = switch (arg) {
598
655
  .None => if (color) "\x1b[2m-\x1b[0m" else "-",
599
656
  .LastStill => "|[still]",
@@ -639,17 +696,17 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
639
696
  .OHKO,
640
697
  => {},
641
698
  .Move => {
642
- const source = ID.from(@intCast(u4, a[i]));
699
+ const source = ID.from(@intCast(a[i]));
643
700
  printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
644
701
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
645
- const target = ID.from(@intCast(u4, a[i]));
702
+ const target = ID.from(@intCast(a[i]));
646
703
  printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
647
- const reason = @intToEnum(Move, a[i]);
704
+ const reason: Move = @enumFromInt(a[i]);
648
705
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
649
706
  if (reason == .From) printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
650
707
  },
651
708
  .Switch => {
652
- const id = ID.from(@intCast(u4, a[i]));
709
+ const id = ID.from(@intCast(a[i]));
653
710
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
654
711
  printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color);
655
712
  printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
@@ -670,9 +727,9 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
670
727
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
671
728
  },
672
729
  .Cant => {
673
- const id = ID.from(@intCast(u4, a[i]));
730
+ const id = ID.from(@intCast(a[i]));
674
731
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
675
- const reason = @intToEnum(Cant, a[i]);
732
+ const reason: Cant = @enumFromInt(a[i]);
676
733
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
677
734
  if (reason == .Disable) {
678
735
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
@@ -685,7 +742,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
685
742
  .SuperEffective,
686
743
  .Resisted,
687
744
  => {
688
- const id = ID.from(@intCast(u4, a[i]));
745
+ const id = ID.from(@intCast(a[i]));
689
746
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
690
747
  },
691
748
  .Turn => {
@@ -695,9 +752,11 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
695
752
  };
696
753
  printc(" {d}", .{turn}, a, b, &i, 2, color);
697
754
  },
698
- .Win => printc(" {s}", .{@tagName(@intToEnum(Player, a[i]))}, a, b, &i, 1, color),
755
+ .Win => {
756
+ printc(" {s}", .{@tagName(@as(Player, @enumFromInt(a[i])))}, a, b, &i, 1, color);
757
+ },
699
758
  .Damage, .Heal => {
700
- var id = ID.from(@intCast(u4, a[i]));
759
+ var id = ID.from(@intCast(a[i]));
701
760
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
702
761
  switch (endian) {
703
762
  .Big => {
@@ -715,91 +774,92 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
715
774
  }
716
775
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
717
776
  if (arg == .Damage) {
718
- const reason = a[i];
719
- printc(" {s}", .{@tagName(@intToEnum(Damage, reason))}, a, b, &i, 1, color);
720
- if (reason == @enumToInt(Damage.RecoilOf)) {
721
- id = ID.from(@intCast(u4, a[i]));
777
+ const reason: Damage = @enumFromInt(a[i]);
778
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
779
+ if (reason == .RecoilOf) {
780
+ id = ID.from(@intCast(a[i]));
722
781
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
723
782
  }
724
783
  } else {
725
- const reason = @intToEnum(Heal, a[i]);
784
+ const reason: Heal = @enumFromInt(a[i]);
726
785
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
727
786
  if (reason == .Drain) {
728
- id = ID.from(@intCast(u4, a[i]));
787
+ id = ID.from(@intCast(a[i]));
729
788
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
730
789
  }
731
790
  }
732
791
  },
733
792
  .Status => {
734
- const id = ID.from(@intCast(u4, a[i]));
793
+ const id = ID.from(@intCast(a[i]));
735
794
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
736
795
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
737
- const reason = @intToEnum(Status, a[i]);
796
+ const reason: Status = @enumFromInt(a[i]);
738
797
  printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
739
798
  if (reason == .From) printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
740
799
  },
741
800
  .CureStatus => {
742
- const id = ID.from(@intCast(u4, a[i]));
801
+ const id = ID.from(@intCast(a[i]));
743
802
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
744
803
  printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
745
- printc(" {s}", .{@tagName(@intToEnum(CureStatus, a[i]))}, a, b, &i, 1, color);
804
+ const reason: CureStatus = @enumFromInt(a[i]);
805
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
746
806
  },
747
807
  .Boost => {
748
- const id = ID.from(@intCast(u4, a[i]));
808
+ const id = ID.from(@intCast(a[i]));
749
809
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
750
- printc(" {s}", .{@tagName(@intToEnum(Boost, a[i]))}, a, b, &i, 1, color);
810
+ printc(" {s}", .{@tagName(@as(Boost, @enumFromInt(a[i])))}, a, b, &i, 1, color);
751
811
  printc(" {d}", .{a[i]}, a, b, &i, 1, color);
752
812
  },
753
813
  .Fail => {
754
- const id = ID.from(@intCast(u4, a[i]));
814
+ const id = ID.from(@intCast(a[i]));
755
815
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
756
- printc(" {s}", .{@tagName(@intToEnum(Fail, a[i]))}, a, b, &i, 1, color);
816
+ printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
757
817
  },
758
818
  .HitCount => {
759
- const id = ID.from(@intCast(u4, a[i]));
819
+ const id = ID.from(@intCast(a[i]));
760
820
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
761
821
  printc(" {d}", .{a[i]}, a, b, &i, 1, color);
762
822
  },
763
823
  .Prepare => {
764
- const id = ID.from(@intCast(u4, a[i]));
824
+ const id = ID.from(@intCast(a[i]));
765
825
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
766
826
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
767
827
  },
768
828
  .Activate => {
769
- const id = ID.from(@intCast(u4, a[i]));
829
+ const id = ID.from(@intCast(a[i]));
770
830
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
771
- printc(" {s}", .{@tagName(@intToEnum(Activate, a[i]))}, a, b, &i, 1, color);
831
+ printc(" {s}", .{@tagName(@as(Activate, @enumFromInt(a[i])))}, a, b, &i, 1, color);
772
832
  },
773
833
  .Start => {
774
- const id = ID.from(@intCast(u4, a[i]));
834
+ const id = ID.from(@intCast(a[i]));
775
835
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
776
836
  const reason = a[i];
777
- printc(" {s}", .{@tagName(@intToEnum(Start, reason))}, a, b, &i, 1, color);
778
- if (@intToEnum(Start, reason) == .TypeChange) {
779
- const types = @bitCast(gen1.Types, a[i]);
837
+ printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
838
+ if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
839
+ const types = @as(gen1.Types, @bitCast(a[i]));
780
840
  const args = .{
781
- formatter(.Type, @enumToInt(types.type1)),
782
- formatter(.Type, @enumToInt(types.type2)),
841
+ formatter(.Type, @intFromEnum(types.type1)),
842
+ formatter(.Type, @intFromEnum(types.type2)),
783
843
  };
784
844
  printc(" {s}/{s}", args, a, b, &i, 1, color);
785
- } else if (reason >= @enumToInt(Start.Disable)) {
845
+ } else if (reason >= @intFromEnum(Start.Disable)) {
786
846
  printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
787
847
  }
788
848
  },
789
849
  .End => {
790
- const id = ID.from(@intCast(u4, a[i]));
850
+ const id = ID.from(@intCast(a[i]));
791
851
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
792
- printc(" {s}", .{@tagName(@intToEnum(End, a[i]))}, a, b, &i, 1, color);
852
+ printc(" {s}", .{@tagName(@as(End, @enumFromInt(a[i])))}, a, b, &i, 1, color);
793
853
  },
794
854
  .Immune => {
795
- const id = ID.from(@intCast(u4, a[i]));
855
+ const id = ID.from(@intCast(a[i]));
796
856
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
797
- printc(" {s}", .{@tagName(@intToEnum(Immune, a[i]))}, a, b, &i, 1, color);
857
+ printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
798
858
  },
799
859
  .Transform => {
800
- const source = ID.from(@intCast(u4, a[i]));
860
+ const source = ID.from(@intCast(a[i]));
801
861
  printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
802
- const target = ID.from(@intCast(u4, a[i]));
862
+ const target = ID.from(@intCast(a[i]));
803
863
  printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
804
864
  },
805
865
  else => unreachable,
@@ -838,7 +898,8 @@ pub fn expectLog(
838
898
  actual: []const u8,
839
899
  offset: usize,
840
900
  ) !void {
841
- if (!trace) return;
901
+ if (!enabled) return;
902
+
842
903
  const color = color: {
843
904
  if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
844
905
  break :color true;
@@ -881,7 +942,7 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
881
942
  const endian = builtin.target.cpu.arch.endian();
882
943
 
883
944
  fn N(e: anytype) u8 {
884
- return @enumToInt(e);
945
+ return @intFromEnum(e);
885
946
  }
886
947
 
887
948
  const p1 = Player.P1;
@@ -905,9 +966,9 @@ fn expectLog1(expected: []const u8, actual: []const u8) !void {
905
966
 
906
967
  fn gen1Formatter(kind: Kind, byte: u8) []const u8 {
907
968
  return switch (kind) {
908
- .Move => @tagName(@intToEnum(M, byte)),
909
- .Species => @tagName(@intToEnum(S, byte)),
910
- .Type => @tagName(@intToEnum(gen1.Type, byte)),
969
+ .Move => @tagName(@as(M, @enumFromInt(byte))),
970
+ .Species => @tagName(@as(S, @enumFromInt(byte))),
971
+ .Type => @tagName(@as(gen1.Type, @enumFromInt(byte))),
911
972
  .Status => gen1.Status.name(byte),
912
973
  };
913
974
  }