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