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