@pkmn/engine 0.1.0-dev.e5b5a998 → 0.1.0-dev.f6c1a379
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 +53 -42
- package/build/pkg/addon.js +3 -2
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +24 -2
- package/build/pkg/data/protocol.json +69 -12
- package/build/pkg/data.d.ts +2 -2
- package/build/pkg/gen1.js +13 -16
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/protocol.js +56 -37
- package/build/pkg/protocol.js.map +1 -1
- package/build.zig +82 -57
- package/package.json +33 -15
- package/src/bin/install-pkmn-engine +10 -5
- package/src/lib/binding/node.zig +46 -141
- package/src/lib/binding/wasm.zig +4 -2
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +15 -27
- package/src/lib/common/debug.zig +20 -11
- package/src/lib/common/js.zig +118 -0
- package/src/lib/common/optional.zig +60 -0
- package/src/lib/common/options.zig +9 -0
- package/src/lib/common/protocol.zig +646 -138
- package/src/lib/common/rational.zig +353 -0
- package/src/lib/common/rng.zig +15 -15
- package/src/lib/common/util.zig +12 -0
- package/src/lib/gen1/README.md +257 -177
- package/src/lib/gen1/calc.zig +426 -0
- package/src/lib/gen1/chance.zig +1058 -0
- package/src/lib/gen1/data/moves.zig +168 -170
- package/src/lib/gen1/data/types.zig +3 -3
- package/src/lib/gen1/data.zig +61 -51
- package/src/lib/gen1/helpers.zig +588 -17
- package/src/lib/gen1/mechanics.zig +776 -502
- package/src/lib/gen2/README.md +106 -85
- package/src/lib/gen2/data/items.zig +11 -17
- package/src/lib/gen2/data/moves.zig +639 -562
- package/src/lib/gen2/data/types.zig +127 -25
- package/src/lib/gen2/data.zig +104 -78
- package/src/lib/gen2/helpers.zig +15 -21
- package/src/lib/gen2/mechanics.zig +1444 -11
- package/src/lib/pkmn.zig +61 -2
|
@@ -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) {
|
|
@@ -118,12 +121,19 @@ pub const Cant = enum(u8) {
|
|
|
118
121
|
Disable,
|
|
119
122
|
Recharge,
|
|
120
123
|
PP,
|
|
124
|
+
|
|
125
|
+
Attract,
|
|
121
126
|
};
|
|
122
127
|
|
|
123
128
|
pub const Heal = enum(u8) {
|
|
124
129
|
None,
|
|
125
130
|
Silent,
|
|
126
131
|
Drain,
|
|
132
|
+
|
|
133
|
+
Leftovers,
|
|
134
|
+
Berry,
|
|
135
|
+
BerryJuice,
|
|
136
|
+
GoldBerry,
|
|
127
137
|
};
|
|
128
138
|
|
|
129
139
|
pub const Damage = enum(u8) {
|
|
@@ -133,6 +143,13 @@ pub const Damage = enum(u8) {
|
|
|
133
143
|
Confusion,
|
|
134
144
|
LeechSeed,
|
|
135
145
|
RecoilOf,
|
|
146
|
+
|
|
147
|
+
Bind,
|
|
148
|
+
Wrap,
|
|
149
|
+
FireSpin,
|
|
150
|
+
Clamp,
|
|
151
|
+
Whirlpool,
|
|
152
|
+
Spikes,
|
|
136
153
|
};
|
|
137
154
|
|
|
138
155
|
pub const Status = enum(u8) {
|
|
@@ -177,6 +194,16 @@ pub const Activate = enum(u8) {
|
|
|
177
194
|
Struggle,
|
|
178
195
|
Substitute,
|
|
179
196
|
Splash,
|
|
197
|
+
|
|
198
|
+
Attract,
|
|
199
|
+
LockOn,
|
|
200
|
+
Bind,
|
|
201
|
+
Wrap,
|
|
202
|
+
FireSpin,
|
|
203
|
+
Clamp,
|
|
204
|
+
Whirlpool,
|
|
205
|
+
|
|
206
|
+
BeatUp, // FIXME of
|
|
180
207
|
};
|
|
181
208
|
|
|
182
209
|
pub const Start = enum(u8) {
|
|
@@ -194,6 +221,18 @@ pub const Start = enum(u8) {
|
|
|
194
221
|
|
|
195
222
|
Disable,
|
|
196
223
|
Mimic,
|
|
224
|
+
|
|
225
|
+
Nightmare,
|
|
226
|
+
Curse,
|
|
227
|
+
Foresight,
|
|
228
|
+
Encore,
|
|
229
|
+
FutureSight,
|
|
230
|
+
|
|
231
|
+
PerishSong0,
|
|
232
|
+
PerishSong1,
|
|
233
|
+
PerishSong2,
|
|
234
|
+
PerishSong3,
|
|
235
|
+
PerishSong3Silent,
|
|
197
236
|
};
|
|
198
237
|
|
|
199
238
|
pub const End = enum(u8) {
|
|
@@ -202,16 +241,27 @@ pub const End = enum(u8) {
|
|
|
202
241
|
Bide,
|
|
203
242
|
Substitute,
|
|
204
243
|
|
|
205
|
-
|
|
244
|
+
Nightmare,
|
|
245
|
+
Curse,
|
|
246
|
+
Foresight,
|
|
247
|
+
Encore,
|
|
248
|
+
FutureSight,
|
|
249
|
+
LeechSeed,
|
|
250
|
+
Bind,
|
|
251
|
+
Wrap,
|
|
252
|
+
FireSpin,
|
|
253
|
+
Clamp,
|
|
254
|
+
Whirlpool,
|
|
255
|
+
|
|
206
256
|
DisableSilent,
|
|
207
257
|
ConfusionSilent,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
258
|
+
MistSilent,
|
|
259
|
+
FocusEnergySilent,
|
|
260
|
+
LeechSeedSilent,
|
|
261
|
+
ToxicSilent,
|
|
262
|
+
LightScreenSilent,
|
|
263
|
+
ReflectSilent,
|
|
264
|
+
BideSilent,
|
|
215
265
|
};
|
|
216
266
|
|
|
217
267
|
pub const Immune = enum(u8) {
|
|
@@ -219,8 +269,34 @@ pub const Immune = enum(u8) {
|
|
|
219
269
|
OHKO,
|
|
220
270
|
};
|
|
221
271
|
|
|
272
|
+
pub const EndItem = enum(u8) {
|
|
273
|
+
None,
|
|
274
|
+
Eat,
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
pub const SetHP = enum(u8) {
|
|
278
|
+
None,
|
|
279
|
+
Silent,
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
pub const Side = enum(u8) {
|
|
283
|
+
Safeguard,
|
|
284
|
+
Reflect,
|
|
285
|
+
LightScreen,
|
|
286
|
+
Spikes,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
pub const Weather = enum(u8) {
|
|
290
|
+
None,
|
|
291
|
+
Upkeep,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
/// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
|
|
295
|
+
/// Ignores anything sent to it, though protocol logging should additionally be turned off
|
|
296
|
+
/// entirely with `options.log`.
|
|
222
297
|
pub const NULL = Log(@TypeOf(std.io.null_writer)){ .writer = std.io.null_writer };
|
|
223
298
|
|
|
299
|
+
/// Logs protocol information to its `Writer` during a battle update when `options.log` is enabled.
|
|
224
300
|
pub fn Log(comptime Writer: type) type {
|
|
225
301
|
return struct {
|
|
226
302
|
const Self = @This();
|
|
@@ -231,12 +307,13 @@ pub fn Log(comptime Writer: type) type {
|
|
|
231
307
|
|
|
232
308
|
pub fn move(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
|
|
233
309
|
if (!enabled) return;
|
|
310
|
+
|
|
234
311
|
assert(m != .None);
|
|
235
312
|
try self.writer.writeAll(&.{
|
|
236
313
|
@intFromEnum(ArgType.Move),
|
|
237
|
-
@
|
|
314
|
+
@as(u8, @bitCast(source)),
|
|
238
315
|
@intFromEnum(m),
|
|
239
|
-
@
|
|
316
|
+
@as(u8, @bitCast(target)),
|
|
240
317
|
});
|
|
241
318
|
const none = &[_]u8{@intFromEnum(Move.None)};
|
|
242
319
|
try self.writer.writeAll(switch (@typeInfo(@TypeOf(from))) {
|
|
@@ -253,9 +330,22 @@ pub fn Log(comptime Writer: type) type {
|
|
|
253
330
|
}
|
|
254
331
|
|
|
255
332
|
pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void {
|
|
333
|
+
return switchDrag(self, .Switch, ident, pokemon);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
fn switchDrag(self: Self, arg: ArgType, ident: ID, pokemon: anytype) Error!void {
|
|
256
337
|
if (!enabled) return;
|
|
257
|
-
|
|
258
|
-
try self.writer.writeAll(&.{ @intFromEnum(
|
|
338
|
+
|
|
339
|
+
try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(ident)) });
|
|
340
|
+
if (@hasField(@TypeOf(pokemon.*), "dvs")) {
|
|
341
|
+
try self.writer.writeAll(&.{
|
|
342
|
+
@intFromEnum(pokemon.species),
|
|
343
|
+
@intFromEnum(pokemon.dvs.gender),
|
|
344
|
+
pokemon.level,
|
|
345
|
+
});
|
|
346
|
+
} else {
|
|
347
|
+
try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level });
|
|
348
|
+
}
|
|
259
349
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
260
350
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
261
351
|
try self.writer.writeAll(&.{pokemon.status});
|
|
@@ -263,19 +353,21 @@ pub fn Log(comptime Writer: type) type {
|
|
|
263
353
|
|
|
264
354
|
pub fn cant(self: Self, ident: ID, reason: Cant) Error!void {
|
|
265
355
|
if (!enabled) return;
|
|
356
|
+
|
|
266
357
|
assert(reason != .Disable);
|
|
267
358
|
try self.writer.writeAll(&.{
|
|
268
359
|
@intFromEnum(ArgType.Cant),
|
|
269
|
-
@
|
|
360
|
+
@as(u8, @bitCast(ident)),
|
|
270
361
|
@intFromEnum(reason),
|
|
271
362
|
});
|
|
272
363
|
}
|
|
273
364
|
|
|
274
365
|
pub fn disabled(self: Self, ident: ID, m: anytype) Error!void {
|
|
275
366
|
if (!enabled) return;
|
|
367
|
+
|
|
276
368
|
try self.writer.writeAll(&.{
|
|
277
369
|
@intFromEnum(ArgType.Cant),
|
|
278
|
-
@
|
|
370
|
+
@as(u8, @bitCast(ident)),
|
|
279
371
|
@intFromEnum(Cant.Disable),
|
|
280
372
|
@intFromEnum(m),
|
|
281
373
|
});
|
|
@@ -283,12 +375,14 @@ pub fn Log(comptime Writer: type) type {
|
|
|
283
375
|
|
|
284
376
|
pub fn faint(self: Self, ident: ID, done: bool) Error!void {
|
|
285
377
|
if (!enabled) return;
|
|
286
|
-
|
|
378
|
+
|
|
379
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) });
|
|
287
380
|
if (done) try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
288
381
|
}
|
|
289
382
|
|
|
290
383
|
pub fn turn(self: Self, num: u16) Error!void {
|
|
291
384
|
if (!enabled) return;
|
|
385
|
+
|
|
292
386
|
try self.writer.writeByte(@intFromEnum(ArgType.Turn));
|
|
293
387
|
try self.writer.writeIntNative(u16, num);
|
|
294
388
|
try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
@@ -296,6 +390,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
296
390
|
|
|
297
391
|
pub fn win(self: Self, player: Player) Error!void {
|
|
298
392
|
if (!enabled) return;
|
|
393
|
+
|
|
299
394
|
try self.writer.writeAll(&.{
|
|
300
395
|
@intFromEnum(ArgType.Win),
|
|
301
396
|
@intFromEnum(player),
|
|
@@ -305,13 +400,15 @@ pub fn Log(comptime Writer: type) type {
|
|
|
305
400
|
|
|
306
401
|
pub fn tie(self: Self) Error!void {
|
|
307
402
|
if (!enabled) return;
|
|
403
|
+
|
|
308
404
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
|
|
309
405
|
}
|
|
310
406
|
|
|
311
407
|
pub fn damage(self: Self, ident: ID, pokemon: anytype, reason: Damage) Error!void {
|
|
312
408
|
if (!enabled) return;
|
|
409
|
+
|
|
313
410
|
assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed));
|
|
314
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @
|
|
411
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
|
|
315
412
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
316
413
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
317
414
|
try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
|
|
@@ -325,21 +422,23 @@ pub fn Log(comptime Writer: type) type {
|
|
|
325
422
|
source: ID,
|
|
326
423
|
) Error!void {
|
|
327
424
|
if (!enabled) return;
|
|
425
|
+
|
|
328
426
|
assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf));
|
|
329
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @
|
|
427
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
|
|
330
428
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
331
429
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
332
430
|
try self.writer.writeAll(&.{
|
|
333
431
|
pokemon.status,
|
|
334
432
|
@intFromEnum(reason),
|
|
335
|
-
@
|
|
433
|
+
@as(u8, @bitCast(source)),
|
|
336
434
|
});
|
|
337
435
|
}
|
|
338
436
|
|
|
339
437
|
pub fn heal(self: Self, ident: ID, pokemon: anytype, reason: Heal) Error!void {
|
|
340
438
|
if (!enabled) return;
|
|
439
|
+
|
|
341
440
|
assert(reason != .Drain);
|
|
342
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @
|
|
441
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(ident)) });
|
|
343
442
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
344
443
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
345
444
|
try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
|
|
@@ -347,22 +446,24 @@ pub fn Log(comptime Writer: type) type {
|
|
|
347
446
|
|
|
348
447
|
pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
|
|
349
448
|
if (!enabled) return;
|
|
350
|
-
|
|
449
|
+
|
|
450
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
|
|
351
451
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
352
452
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
353
453
|
try self.writer.writeAll(&.{
|
|
354
454
|
pokemon.status,
|
|
355
455
|
@intFromEnum(Heal.Drain),
|
|
356
|
-
@
|
|
456
|
+
@as(u8, @bitCast(target)),
|
|
357
457
|
});
|
|
358
458
|
}
|
|
359
459
|
|
|
360
460
|
pub fn status(self: Self, ident: ID, value: u8, reason: Status) Error!void {
|
|
361
461
|
if (!enabled) return;
|
|
462
|
+
|
|
362
463
|
assert(reason != .From);
|
|
363
464
|
try self.writer.writeAll(&.{
|
|
364
465
|
@intFromEnum(ArgType.Status),
|
|
365
|
-
@
|
|
466
|
+
@as(u8, @bitCast(ident)),
|
|
366
467
|
value,
|
|
367
468
|
@intFromEnum(reason),
|
|
368
469
|
});
|
|
@@ -370,9 +471,10 @@ pub fn Log(comptime Writer: type) type {
|
|
|
370
471
|
|
|
371
472
|
pub fn statusFrom(self: Self, ident: ID, value: u8, m: anytype) Error!void {
|
|
372
473
|
if (!enabled) return;
|
|
474
|
+
|
|
373
475
|
try self.writer.writeAll(&.{
|
|
374
476
|
@intFromEnum(ArgType.Status),
|
|
375
|
-
@
|
|
477
|
+
@as(u8, @bitCast(ident)),
|
|
376
478
|
value,
|
|
377
479
|
@intFromEnum(Status.From),
|
|
378
480
|
@intFromEnum(m),
|
|
@@ -381,9 +483,10 @@ pub fn Log(comptime Writer: type) type {
|
|
|
381
483
|
|
|
382
484
|
pub fn curestatus(self: Self, ident: ID, value: u8, reason: CureStatus) Error!void {
|
|
383
485
|
if (!enabled) return;
|
|
486
|
+
|
|
384
487
|
try self.writer.writeAll(&.{
|
|
385
488
|
@intFromEnum(ArgType.CureStatus),
|
|
386
|
-
@
|
|
489
|
+
@as(u8, @bitCast(ident)),
|
|
387
490
|
value,
|
|
388
491
|
@intFromEnum(reason),
|
|
389
492
|
});
|
|
@@ -391,98 +494,113 @@ pub fn Log(comptime Writer: type) type {
|
|
|
391
494
|
|
|
392
495
|
pub fn boost(self: Self, ident: ID, reason: Boost, num: i8) Error!void {
|
|
393
496
|
if (!enabled) return;
|
|
497
|
+
|
|
394
498
|
assert(num != 0 and (reason != .Rage or num > 0));
|
|
395
499
|
try self.writer.writeAll(&.{
|
|
396
500
|
@intFromEnum(ArgType.Boost),
|
|
397
|
-
@
|
|
501
|
+
@as(u8, @bitCast(ident)),
|
|
398
502
|
@intFromEnum(reason),
|
|
399
|
-
@
|
|
503
|
+
@as(u8, @intCast(num + 6)),
|
|
400
504
|
});
|
|
401
505
|
}
|
|
402
506
|
|
|
403
507
|
pub fn clearallboost(self: Self) Error!void {
|
|
404
508
|
if (!enabled) return;
|
|
509
|
+
|
|
405
510
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
|
|
406
511
|
}
|
|
407
512
|
|
|
408
513
|
pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
|
|
409
514
|
if (!enabled) return;
|
|
515
|
+
|
|
410
516
|
try self.writer.writeAll(&.{
|
|
411
517
|
@intFromEnum(ArgType.Fail),
|
|
412
|
-
@
|
|
518
|
+
@as(u8, @bitCast(ident)),
|
|
413
519
|
@intFromEnum(reason),
|
|
414
520
|
});
|
|
415
521
|
}
|
|
416
522
|
|
|
417
523
|
pub fn miss(self: Self, source: ID) Error!void {
|
|
418
524
|
if (!enabled) return;
|
|
419
|
-
|
|
525
|
+
|
|
526
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) });
|
|
420
527
|
}
|
|
421
528
|
|
|
422
529
|
pub fn hitcount(self: Self, ident: ID, num: u8) Error!void {
|
|
423
530
|
if (!enabled) return;
|
|
531
|
+
|
|
424
532
|
try self.writer.writeAll(&.{
|
|
425
533
|
@intFromEnum(ArgType.HitCount),
|
|
426
|
-
@
|
|
534
|
+
@as(u8, @bitCast(ident)),
|
|
427
535
|
num,
|
|
428
536
|
});
|
|
429
537
|
}
|
|
430
538
|
|
|
431
539
|
pub fn prepare(self: Self, source: ID, m: anytype) Error!void {
|
|
432
540
|
if (!enabled) return;
|
|
541
|
+
|
|
433
542
|
try self.writer.writeAll(&.{
|
|
434
543
|
@intFromEnum(ArgType.Prepare),
|
|
435
|
-
@
|
|
544
|
+
@as(u8, @bitCast(source)),
|
|
436
545
|
@intFromEnum(m),
|
|
437
546
|
});
|
|
438
547
|
}
|
|
439
548
|
|
|
440
549
|
pub fn mustrecharge(self: Self, ident: ID) Error!void {
|
|
441
550
|
if (!enabled) return;
|
|
442
|
-
|
|
551
|
+
|
|
552
|
+
try self.writer.writeAll(&.{
|
|
553
|
+
@intFromEnum(ArgType.MustRecharge),
|
|
554
|
+
@as(u8, @bitCast(ident)),
|
|
555
|
+
});
|
|
443
556
|
}
|
|
444
557
|
|
|
445
558
|
pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
|
|
446
559
|
if (!enabled) return;
|
|
560
|
+
|
|
447
561
|
try self.writer.writeAll(&.{
|
|
448
562
|
@intFromEnum(ArgType.Activate),
|
|
449
|
-
@
|
|
563
|
+
@as(u8, @bitCast(ident)),
|
|
450
564
|
@intFromEnum(reason),
|
|
451
565
|
});
|
|
452
566
|
}
|
|
453
567
|
|
|
454
568
|
pub fn fieldactivate(self: Self) Error!void {
|
|
455
569
|
if (!enabled) return;
|
|
570
|
+
|
|
456
571
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
|
|
457
572
|
}
|
|
458
573
|
|
|
459
574
|
pub fn start(self: Self, ident: ID, reason: Start) Error!void {
|
|
460
575
|
if (!enabled) return;
|
|
576
|
+
|
|
461
577
|
assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
|
|
462
578
|
try self.writer.writeAll(&.{
|
|
463
579
|
@intFromEnum(ArgType.Start),
|
|
464
|
-
@
|
|
580
|
+
@as(u8, @bitCast(ident)),
|
|
465
581
|
@intFromEnum(reason),
|
|
466
582
|
});
|
|
467
583
|
}
|
|
468
584
|
|
|
469
585
|
pub fn typechange(self: Self, source: ID, types: anytype, target: ID) Error!void {
|
|
470
586
|
if (!enabled) return;
|
|
587
|
+
|
|
471
588
|
try self.writer.writeAll(&.{
|
|
472
589
|
@intFromEnum(ArgType.Start),
|
|
473
|
-
@
|
|
590
|
+
@as(u8, @bitCast(source)),
|
|
474
591
|
@intFromEnum(Start.TypeChange),
|
|
475
|
-
@
|
|
476
|
-
@
|
|
592
|
+
@as(u8, @bitCast(types)),
|
|
593
|
+
@as(u8, @bitCast(target)),
|
|
477
594
|
});
|
|
478
595
|
}
|
|
479
596
|
|
|
480
597
|
pub fn startEffect(self: Self, ident: ID, reason: Start, m: anytype) Error!void {
|
|
481
598
|
if (!enabled) return;
|
|
599
|
+
|
|
482
600
|
assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
|
|
483
601
|
try self.writer.writeAll(&.{
|
|
484
602
|
@intFromEnum(ArgType.Start),
|
|
485
|
-
@
|
|
603
|
+
@as(u8, @bitCast(ident)),
|
|
486
604
|
@intFromEnum(reason),
|
|
487
605
|
@intFromEnum(m),
|
|
488
606
|
});
|
|
@@ -490,68 +608,211 @@ pub fn Log(comptime Writer: type) type {
|
|
|
490
608
|
|
|
491
609
|
pub fn end(self: Self, ident: ID, reason: End) Error!void {
|
|
492
610
|
if (!enabled) return;
|
|
611
|
+
|
|
493
612
|
try self.writer.writeAll(&.{
|
|
494
613
|
@intFromEnum(ArgType.End),
|
|
495
|
-
@
|
|
614
|
+
@as(u8, @bitCast(ident)),
|
|
496
615
|
@intFromEnum(reason),
|
|
497
616
|
});
|
|
498
617
|
}
|
|
499
618
|
|
|
500
619
|
pub fn ohko(self: Self) Error!void {
|
|
501
620
|
if (!enabled) return;
|
|
621
|
+
|
|
502
622
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
|
|
503
623
|
}
|
|
504
624
|
|
|
505
625
|
pub fn crit(self: Self, ident: ID) Error!void {
|
|
506
626
|
if (!enabled) return;
|
|
507
|
-
|
|
627
|
+
|
|
628
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) });
|
|
508
629
|
}
|
|
509
630
|
|
|
510
631
|
pub fn supereffective(self: Self, ident: ID) Error!void {
|
|
511
632
|
if (!enabled) return;
|
|
633
|
+
|
|
512
634
|
try self.writer.writeAll(&.{
|
|
513
635
|
@intFromEnum(ArgType.SuperEffective),
|
|
514
|
-
@
|
|
636
|
+
@as(u8, @bitCast(ident)),
|
|
515
637
|
});
|
|
516
638
|
}
|
|
517
639
|
|
|
518
640
|
pub fn resisted(self: Self, ident: ID) Error!void {
|
|
519
641
|
if (!enabled) return;
|
|
520
|
-
|
|
642
|
+
|
|
643
|
+
try self.writer.writeAll(&.{
|
|
644
|
+
@intFromEnum(ArgType.Resisted),
|
|
645
|
+
@as(u8, @bitCast(ident)),
|
|
646
|
+
});
|
|
521
647
|
}
|
|
522
648
|
|
|
523
649
|
pub fn immune(self: Self, ident: ID, reason: Immune) Error!void {
|
|
524
650
|
if (!enabled) return;
|
|
651
|
+
|
|
525
652
|
try self.writer.writeAll(&.{
|
|
526
653
|
@intFromEnum(ArgType.Immune),
|
|
527
|
-
@
|
|
654
|
+
@as(u8, @bitCast(ident)),
|
|
528
655
|
@intFromEnum(reason),
|
|
529
656
|
});
|
|
530
657
|
}
|
|
531
658
|
|
|
532
659
|
pub fn transform(self: Self, source: ID, target: ID) Error!void {
|
|
533
660
|
if (!enabled) return;
|
|
661
|
+
|
|
534
662
|
try self.writer.writeAll(&.{
|
|
535
663
|
@intFromEnum(ArgType.Transform),
|
|
536
|
-
@
|
|
537
|
-
@
|
|
664
|
+
@as(u8, @bitCast(source)),
|
|
665
|
+
@as(u8, @bitCast(target)),
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
pub fn drag(self: Self, ident: ID, pokemon: anytype) Error!void {
|
|
670
|
+
return switchDrag(self, .Drag, ident, pokemon);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
pub fn item(self: Self, target: ID, i: anytype, source: ID) Error!void {
|
|
674
|
+
if (!enabled) return;
|
|
675
|
+
|
|
676
|
+
try self.writer.writeAll(&.{
|
|
677
|
+
@intFromEnum(ArgType.Item),
|
|
678
|
+
@as(u8, @bitCast(target)),
|
|
679
|
+
@intFromEnum(i),
|
|
680
|
+
@as(u8, @bitCast(source)),
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
pub fn enditem(self: Self, ident: ID, i: anytype, reason: EndItem) Error!void {
|
|
685
|
+
if (!enabled) return;
|
|
686
|
+
|
|
687
|
+
try self.writer.writeAll(&.{
|
|
688
|
+
@intFromEnum(ArgType.EndItem),
|
|
689
|
+
@as(u8, @bitCast(ident)),
|
|
690
|
+
@intFromEnum(i),
|
|
691
|
+
@intFromEnum(reason),
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
pub fn cureteam(self: Self, source: ID) Error!void {
|
|
696
|
+
if (!enabled) return;
|
|
697
|
+
|
|
698
|
+
try self.writer.writeAll(&.{
|
|
699
|
+
@intFromEnum(ArgType.CureTeam),
|
|
700
|
+
@as(u8, @bitCast(source)),
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
pub fn sethp(self: Self, ident: ID, pokemon: anytype, reason: SetHP) Error!void {
|
|
705
|
+
if (!enabled) return;
|
|
706
|
+
|
|
707
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(ident)) });
|
|
708
|
+
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
709
|
+
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
710
|
+
try self.writer.writeAll(&.{pokemon.status});
|
|
711
|
+
try self.writer.writeByte(@intFromEnum(reason));
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
pub fn setboost(self: Self, ident: ID, num: i8) Error!void {
|
|
715
|
+
if (!enabled) return;
|
|
716
|
+
|
|
717
|
+
try self.writer.writeAll(&.{
|
|
718
|
+
@intFromEnum(ArgType.SetBoost),
|
|
719
|
+
@as(u8, @bitCast(ident)),
|
|
720
|
+
@as(u8, @intCast(num + 6)),
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
pub fn copyboost(self: Self, source: ID, target: ID) Error!void {
|
|
725
|
+
if (!enabled) return;
|
|
726
|
+
|
|
727
|
+
try self.writer.writeAll(&.{
|
|
728
|
+
@intFromEnum(ArgType.CopyBoost),
|
|
729
|
+
@as(u8, @bitCast(source)),
|
|
730
|
+
@as(u8, @bitCast(target)),
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
pub fn sidestart(self: Self, player: Player, reason: Side) Error!void {
|
|
735
|
+
if (!enabled) return;
|
|
736
|
+
|
|
737
|
+
try self.writer.writeAll(&.{
|
|
738
|
+
@intFromEnum(ArgType.SideStart),
|
|
739
|
+
@intFromEnum(player),
|
|
740
|
+
@intFromEnum(reason),
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
pub fn sideend(self: Self, player: Player, reason: Side) Error!void {
|
|
745
|
+
if (!enabled) return;
|
|
746
|
+
|
|
747
|
+
assert(@intFromEnum(reason) != @intFromEnum(Side.Spikes));
|
|
748
|
+
try self.writer.writeAll(&.{
|
|
749
|
+
@intFromEnum(ArgType.SideEnd),
|
|
750
|
+
@intFromEnum(player),
|
|
751
|
+
@intFromEnum(reason),
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
pub fn spikesend(self: Self, player: Player, m: anytype, source: ID) Error!void {
|
|
756
|
+
if (!enabled) return;
|
|
757
|
+
|
|
758
|
+
try self.writer.writeAll(&.{
|
|
759
|
+
@intFromEnum(ArgType.SideEnd),
|
|
760
|
+
@intFromEnum(player),
|
|
761
|
+
@intFromEnum(Side.Spikes),
|
|
762
|
+
@intFromEnum(m),
|
|
763
|
+
@as(u8, @bitCast(source)),
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
pub fn singlemove(self: Self, ident: ID, m: anytype) Error!void {
|
|
768
|
+
return single(self, .SingleMove, ident, m);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
pub fn singleturn(self: Self, ident: ID, m: anytype) Error!void {
|
|
772
|
+
return single(self, .SingleTurn, ident, m);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
fn single(self: Self, arg: ArgType, ident: ID, m: anytype) Error!void {
|
|
776
|
+
if (!enabled) return;
|
|
777
|
+
|
|
778
|
+
try self.writer.writeAll(&.{
|
|
779
|
+
@intFromEnum(arg),
|
|
780
|
+
@as(u8, @bitCast(ident)),
|
|
781
|
+
@intFromEnum(m),
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
pub fn weather(self: Self, w: anytype, reason: Weather) Error!void {
|
|
786
|
+
if (!enabled) return;
|
|
787
|
+
|
|
788
|
+
assert(!(w == .None and reason == .Upkeep));
|
|
789
|
+
try self.writer.writeAll(&.{
|
|
790
|
+
@intFromEnum(ArgType.Weather),
|
|
791
|
+
@intFromEnum(w),
|
|
792
|
+
@intFromEnum(reason),
|
|
538
793
|
});
|
|
539
794
|
}
|
|
540
795
|
|
|
541
796
|
pub fn laststill(self: Self) Error!void {
|
|
542
797
|
if (!enabled) return;
|
|
798
|
+
|
|
543
799
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
|
|
544
800
|
}
|
|
545
801
|
|
|
546
802
|
pub fn lastmiss(self: Self) Error!void {
|
|
547
803
|
if (!enabled) return;
|
|
804
|
+
|
|
548
805
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
|
|
549
806
|
}
|
|
550
807
|
};
|
|
551
808
|
}
|
|
552
809
|
|
|
810
|
+
/// `Log` type backed by the optimized `ByteStream.Writer`.
|
|
553
811
|
pub const FixedLog = Log(ByteStream.Writer);
|
|
554
812
|
|
|
813
|
+
/// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
|
|
814
|
+
/// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
|
|
815
|
+
/// should not be used for general purpose writing.
|
|
555
816
|
pub const ByteStream = struct {
|
|
556
817
|
buffer: []u8,
|
|
557
818
|
pos: usize = 0,
|
|
@@ -592,15 +853,19 @@ pub const ByteStream = struct {
|
|
|
592
853
|
}
|
|
593
854
|
};
|
|
594
855
|
|
|
595
|
-
pub const Kind = enum { Move, Species, Type, Status };
|
|
596
|
-
pub const Formatter = fn (Kind, u8) []const u8;
|
|
856
|
+
pub const Kind = enum { Move, Species, Type, Status, Item, Weather };
|
|
597
857
|
|
|
598
|
-
pub fn format(
|
|
858
|
+
pub fn format(
|
|
859
|
+
comptime gen: anytype,
|
|
860
|
+
a: []const u8,
|
|
861
|
+
b: ?[]const u8,
|
|
862
|
+
color: bool,
|
|
863
|
+
) void {
|
|
599
864
|
print("\n", .{});
|
|
600
865
|
|
|
601
866
|
var i: usize = 0;
|
|
602
867
|
while (i < a.len) {
|
|
603
|
-
const arg = @enumFromInt(
|
|
868
|
+
const arg: ArgType = @enumFromInt(a[i]);
|
|
604
869
|
const name = switch (arg) {
|
|
605
870
|
.None => if (color) "\x1b[2m-\x1b[0m" else "-",
|
|
606
871
|
.LastStill => "|[still]",
|
|
@@ -633,6 +898,18 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
633
898
|
.Resisted => "|-resisted|",
|
|
634
899
|
.Immune => "|-immune|",
|
|
635
900
|
.Transform => "|-transform|",
|
|
901
|
+
.Drag => "|drag|",
|
|
902
|
+
.Item => "|-item|",
|
|
903
|
+
.EndItem => "|-enditem|",
|
|
904
|
+
.CureTeam => "|-cureteam|",
|
|
905
|
+
.SetHP => "|-sethp|",
|
|
906
|
+
.SetBoost => "|-setboost|",
|
|
907
|
+
.CopyBoost => "|-copyboost|",
|
|
908
|
+
.SideStart => "|-sidestart|",
|
|
909
|
+
.SideEnd => "|-sideend|",
|
|
910
|
+
.SingleMove => "|-singlemove|",
|
|
911
|
+
.SingleTurn => "|-singleturn|",
|
|
912
|
+
.Weather => "|-weather|",
|
|
636
913
|
else => unreachable,
|
|
637
914
|
};
|
|
638
915
|
printc("{s}", .{name}, a, b, &i, 1, color);
|
|
@@ -646,19 +923,29 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
646
923
|
.OHKO,
|
|
647
924
|
=> {},
|
|
648
925
|
.Move => {
|
|
649
|
-
const source = ID.from(@intCast(
|
|
926
|
+
const source = ID.from(@intCast(a[i]));
|
|
650
927
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
651
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
652
|
-
const target = ID.from(@intCast(
|
|
928
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
929
|
+
const target = ID.from(@intCast(a[i]));
|
|
653
930
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
654
|
-
const reason = @enumFromInt(
|
|
931
|
+
const reason: Move = @enumFromInt(a[i]);
|
|
655
932
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
656
|
-
if (reason == .From)
|
|
933
|
+
if (reason == .From) {
|
|
934
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
935
|
+
}
|
|
657
936
|
},
|
|
658
|
-
.Switch => {
|
|
659
|
-
const id = ID.from(@intCast(
|
|
937
|
+
.Switch, .Drag => {
|
|
938
|
+
const id = ID.from(@intCast(a[i]));
|
|
660
939
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
661
|
-
printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color);
|
|
940
|
+
printc(" {s}", .{formatter(gen, .Species, a[i])}, a, b, &i, 1, color);
|
|
941
|
+
if (@hasDecl(gen, "Gender")) {
|
|
942
|
+
if (a[i] == N(gen.Gender.Unknown)) {
|
|
943
|
+
i += 1;
|
|
944
|
+
} else {
|
|
945
|
+
var gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
|
|
946
|
+
printc(", {s}", .{gender}, a, b, &i, 1, color);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
662
949
|
printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
|
|
663
950
|
switch (endian) {
|
|
664
951
|
.Big => {
|
|
@@ -674,15 +961,15 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
674
961
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
675
962
|
},
|
|
676
963
|
}
|
|
677
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
964
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
678
965
|
},
|
|
679
966
|
.Cant => {
|
|
680
|
-
const id = ID.from(@intCast(
|
|
967
|
+
const id = ID.from(@intCast(a[i]));
|
|
681
968
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
682
|
-
const reason = @enumFromInt(
|
|
969
|
+
const reason: Cant = @enumFromInt(a[i]);
|
|
683
970
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
684
971
|
if (reason == .Disable) {
|
|
685
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
972
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
686
973
|
}
|
|
687
974
|
},
|
|
688
975
|
.Faint,
|
|
@@ -691,8 +978,9 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
691
978
|
.Crit,
|
|
692
979
|
.SuperEffective,
|
|
693
980
|
.Resisted,
|
|
981
|
+
.CureTeam,
|
|
694
982
|
=> {
|
|
695
|
-
const id = ID.from(@intCast(
|
|
983
|
+
const id = ID.from(@intCast(a[i]));
|
|
696
984
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
697
985
|
},
|
|
698
986
|
.Turn => {
|
|
@@ -702,9 +990,11 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
702
990
|
};
|
|
703
991
|
printc(" {d}", .{turn}, a, b, &i, 2, color);
|
|
704
992
|
},
|
|
705
|
-
.Win =>
|
|
993
|
+
.Win => {
|
|
994
|
+
printc(" {s}", .{@tagName(@as(Player, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
995
|
+
},
|
|
706
996
|
.Damage, .Heal => {
|
|
707
|
-
var id = ID.from(@intCast(
|
|
997
|
+
var id = ID.from(@intCast(a[i]));
|
|
708
998
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
709
999
|
switch (endian) {
|
|
710
1000
|
.Big => {
|
|
@@ -720,95 +1010,150 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
720
1010
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
721
1011
|
},
|
|
722
1012
|
}
|
|
723
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1013
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
724
1014
|
if (arg == .Damage) {
|
|
725
|
-
const reason = a[i];
|
|
726
|
-
printc(" {s}", .{@tagName(
|
|
727
|
-
if (reason ==
|
|
728
|
-
id = ID.from(@intCast(
|
|
1015
|
+
const reason: Damage = @enumFromInt(a[i]);
|
|
1016
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1017
|
+
if (reason == .RecoilOf) {
|
|
1018
|
+
id = ID.from(@intCast(a[i]));
|
|
729
1019
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
730
1020
|
}
|
|
731
1021
|
} else {
|
|
732
|
-
const reason = @enumFromInt(
|
|
1022
|
+
const reason: Heal = @enumFromInt(a[i]);
|
|
733
1023
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
734
1024
|
if (reason == .Drain) {
|
|
735
|
-
id = ID.from(@intCast(
|
|
1025
|
+
id = ID.from(@intCast(a[i]));
|
|
736
1026
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
737
1027
|
}
|
|
738
1028
|
}
|
|
739
1029
|
},
|
|
740
1030
|
.Status => {
|
|
741
|
-
const id = ID.from(@intCast(
|
|
1031
|
+
const id = ID.from(@intCast(a[i]));
|
|
742
1032
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
743
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
744
|
-
const reason = @enumFromInt(
|
|
1033
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1034
|
+
const reason: Status = @enumFromInt(a[i]);
|
|
745
1035
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
746
|
-
if (reason == .From)
|
|
1036
|
+
if (reason == .From) {
|
|
1037
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1038
|
+
}
|
|
747
1039
|
},
|
|
748
1040
|
.CureStatus => {
|
|
749
|
-
const id = ID.from(@intCast(
|
|
1041
|
+
const id = ID.from(@intCast(a[i]));
|
|
750
1042
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
751
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
752
|
-
|
|
1043
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1044
|
+
const reason: CureStatus = @enumFromInt(a[i]);
|
|
1045
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
753
1046
|
},
|
|
754
1047
|
.Boost => {
|
|
755
|
-
const id = ID.from(@intCast(
|
|
1048
|
+
const id = ID.from(@intCast(a[i]));
|
|
756
1049
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
757
|
-
printc(" {s}", .{@tagName(@
|
|
1050
|
+
printc(" {s}", .{@tagName(@as(Boost, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
758
1051
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
759
1052
|
},
|
|
760
1053
|
.Fail => {
|
|
761
|
-
const id = ID.from(@intCast(
|
|
1054
|
+
const id = ID.from(@intCast(a[i]));
|
|
762
1055
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
763
|
-
printc(" {s}", .{@tagName(@
|
|
1056
|
+
printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
764
1057
|
},
|
|
765
|
-
.HitCount => {
|
|
766
|
-
const id = ID.from(@intCast(
|
|
1058
|
+
.HitCount, .SetBoost => {
|
|
1059
|
+
const id = ID.from(@intCast(a[i]));
|
|
767
1060
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
768
1061
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
769
1062
|
},
|
|
770
|
-
.Prepare => {
|
|
771
|
-
const id = ID.from(@intCast(
|
|
1063
|
+
.Prepare, .SingleMove, .SingleTurn => {
|
|
1064
|
+
const id = ID.from(@intCast(a[i]));
|
|
772
1065
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
773
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1066
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
774
1067
|
},
|
|
775
1068
|
.Activate => {
|
|
776
|
-
const id = ID.from(@intCast(
|
|
1069
|
+
const id = ID.from(@intCast(a[i]));
|
|
777
1070
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
778
|
-
printc(" {s}", .{@tagName(@
|
|
1071
|
+
printc(" {s}", .{@tagName(@as(Activate, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
779
1072
|
},
|
|
780
1073
|
.Start => {
|
|
781
|
-
const id = ID.from(@intCast(
|
|
1074
|
+
const id = ID.from(@intCast(a[i]));
|
|
782
1075
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
783
1076
|
const reason = a[i];
|
|
784
|
-
printc(" {s}", .{@tagName(@
|
|
785
|
-
if (@
|
|
786
|
-
const types = @
|
|
1077
|
+
printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
|
|
1078
|
+
if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
|
|
1079
|
+
const types = @as(gen1.Types, @bitCast(a[i]));
|
|
787
1080
|
const args = .{
|
|
788
|
-
formatter(.Type, @intFromEnum(types.type1)),
|
|
789
|
-
formatter(.Type, @intFromEnum(types.type2)),
|
|
1081
|
+
formatter(gen, .Type, @intFromEnum(types.type1)),
|
|
1082
|
+
formatter(gen, .Type, @intFromEnum(types.type2)),
|
|
790
1083
|
};
|
|
791
1084
|
printc(" {s}/{s}", args, a, b, &i, 1, color);
|
|
792
1085
|
} else if (reason >= @intFromEnum(Start.Disable)) {
|
|
793
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1086
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
794
1087
|
}
|
|
795
1088
|
},
|
|
796
1089
|
.End => {
|
|
797
|
-
const id = ID.from(@intCast(
|
|
1090
|
+
const id = ID.from(@intCast(a[i]));
|
|
798
1091
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
799
|
-
printc(" {s}", .{@tagName(@
|
|
1092
|
+
printc(" {s}", .{@tagName(@as(End, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
800
1093
|
},
|
|
801
1094
|
.Immune => {
|
|
802
|
-
const id = ID.from(@intCast(
|
|
1095
|
+
const id = ID.from(@intCast(a[i]));
|
|
803
1096
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
804
|
-
printc(" {s}", .{@tagName(@
|
|
1097
|
+
printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
805
1098
|
},
|
|
806
|
-
.Transform => {
|
|
807
|
-
const source = ID.from(@intCast(
|
|
1099
|
+
.Transform, .CopyBoost => {
|
|
1100
|
+
const source = ID.from(@intCast(a[i]));
|
|
808
1101
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
809
|
-
const target = ID.from(@intCast(
|
|
1102
|
+
const target = ID.from(@intCast(a[i]));
|
|
810
1103
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
811
1104
|
},
|
|
1105
|
+
.Item, .EndItem => {
|
|
1106
|
+
var id = ID.from(@intCast(a[i]));
|
|
1107
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1108
|
+
printc(" {s}", .{formatter(gen, .Item, a[i])}, a, b, &i, 1, color);
|
|
1109
|
+
if (arg == .Item) {
|
|
1110
|
+
id = ID.from(@intCast(a[i]));
|
|
1111
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1112
|
+
} else {
|
|
1113
|
+
const reason: EndItem = @enumFromInt(a[i]);
|
|
1114
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1115
|
+
}
|
|
1116
|
+
},
|
|
1117
|
+
.SetHP => {
|
|
1118
|
+
const id = ID.from(@intCast(a[i]));
|
|
1119
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1120
|
+
switch (endian) {
|
|
1121
|
+
.Big => {
|
|
1122
|
+
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1123
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1124
|
+
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1125
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1126
|
+
},
|
|
1127
|
+
.Little => {
|
|
1128
|
+
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1129
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1130
|
+
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1131
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1132
|
+
},
|
|
1133
|
+
}
|
|
1134
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1135
|
+
printc(" {s}", .{@tagName(@as(SetHP, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1136
|
+
},
|
|
1137
|
+
.SideStart => {
|
|
1138
|
+
const id = ID.from(@intCast(a[i]));
|
|
1139
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1140
|
+
printc(" {s}", .{@tagName(@as(Side, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1141
|
+
},
|
|
1142
|
+
.SideEnd => {
|
|
1143
|
+
var id = ID.from(@intCast(a[i]));
|
|
1144
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1145
|
+
const reason: Side = @enumFromInt(a[i]);
|
|
1146
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1147
|
+
if (reason == .Spikes) {
|
|
1148
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1149
|
+
id = ID.from(@intCast(a[i]));
|
|
1150
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1151
|
+
}
|
|
1152
|
+
},
|
|
1153
|
+
.Weather => {
|
|
1154
|
+
printc(" {s}", .{formatter(gen, .Weather, a[i])}, a, b, &i, 1, color);
|
|
1155
|
+
printc(" {s}", .{@tagName(@as(Weather, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1156
|
+
},
|
|
812
1157
|
else => unreachable,
|
|
813
1158
|
}
|
|
814
1159
|
print("\n", .{});
|
|
@@ -840,12 +1185,13 @@ fn printc(
|
|
|
840
1185
|
}
|
|
841
1186
|
|
|
842
1187
|
pub fn expectLog(
|
|
843
|
-
comptime
|
|
1188
|
+
comptime gen: anytype,
|
|
844
1189
|
expected: []const u8,
|
|
845
1190
|
actual: []const u8,
|
|
846
1191
|
offset: usize,
|
|
847
1192
|
) !void {
|
|
848
1193
|
if (!enabled) return;
|
|
1194
|
+
|
|
849
1195
|
const color = color: {
|
|
850
1196
|
if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
|
|
851
1197
|
break :color true;
|
|
@@ -858,8 +1204,8 @@ pub fn expectLog(
|
|
|
858
1204
|
|
|
859
1205
|
expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
|
|
860
1206
|
error.TestExpectedEqual => {
|
|
861
|
-
format(
|
|
862
|
-
format(
|
|
1207
|
+
format(gen, expected, null, color);
|
|
1208
|
+
format(gen, actual, expected, color);
|
|
863
1209
|
return err;
|
|
864
1210
|
},
|
|
865
1211
|
else => return err,
|
|
@@ -899,49 +1245,71 @@ const gen1 = struct {
|
|
|
899
1245
|
pub const helpers = @import("../gen1/helpers.zig");
|
|
900
1246
|
};
|
|
901
1247
|
|
|
1248
|
+
const gen2 = struct {
|
|
1249
|
+
pub usingnamespace @import("../gen2/data.zig");
|
|
1250
|
+
pub const helpers = @import("../gen2/helpers.zig");
|
|
1251
|
+
};
|
|
1252
|
+
|
|
902
1253
|
var buf: [gen1.LOGS_SIZE]u8 = undefined;
|
|
903
|
-
var stream =
|
|
1254
|
+
var stream: ByteStream = .{ .buffer = &buf };
|
|
904
1255
|
var log: FixedLog = .{ .writer = stream.writer() };
|
|
905
1256
|
|
|
906
|
-
const
|
|
907
|
-
const
|
|
1257
|
+
const M1 = gen1.Move;
|
|
1258
|
+
const S1 = gen1.Species;
|
|
1259
|
+
|
|
1260
|
+
const M2 = gen2.Move;
|
|
1261
|
+
const S2 = gen2.Species;
|
|
1262
|
+
const I2 = gen2.Item;
|
|
1263
|
+
const W2 = gen2.Weather;
|
|
908
1264
|
|
|
909
1265
|
fn expectLog1(expected: []const u8, actual: []const u8) !void {
|
|
910
|
-
return expectLog(
|
|
1266
|
+
return expectLog(gen1, expected, actual, 0);
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
fn expectLog2(expected: []const u8, actual: []const u8) !void {
|
|
1270
|
+
return expectLog(gen2, expected, actual, 0);
|
|
911
1271
|
}
|
|
912
1272
|
|
|
913
|
-
fn
|
|
1273
|
+
fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
|
|
914
1274
|
return switch (kind) {
|
|
915
|
-
.Move => @tagName(@
|
|
916
|
-
.Species => @tagName(@
|
|
917
|
-
.Type => @tagName(@
|
|
918
|
-
.Status =>
|
|
1275
|
+
.Move => @tagName(@as(gen.Move, @enumFromInt(byte))),
|
|
1276
|
+
.Species => @tagName(@as(gen.Species, @enumFromInt(byte))),
|
|
1277
|
+
.Type => @tagName(@as(gen.Type, @enumFromInt(byte))),
|
|
1278
|
+
.Status => gen.Status.name(byte),
|
|
1279
|
+
.Item => if (@hasDecl(gen, "Item"))
|
|
1280
|
+
@tagName(@as(gen.Item, @enumFromInt(byte)))
|
|
1281
|
+
else
|
|
1282
|
+
unreachable,
|
|
1283
|
+
.Weather => if (@hasDecl(gen, "Weather"))
|
|
1284
|
+
@tagName(@as(gen.Weather, @enumFromInt(byte)))
|
|
1285
|
+
else
|
|
1286
|
+
unreachable,
|
|
919
1287
|
};
|
|
920
1288
|
}
|
|
921
1289
|
|
|
922
1290
|
test "|move|" {
|
|
923
|
-
try log.move(p2.ident(4),
|
|
1291
|
+
try log.move(p2.ident(4), M1.Thunderbolt, p1.ident(5), null);
|
|
924
1292
|
try expectLog1(
|
|
925
|
-
&.{ N(ArgType.Move), 0b1100, N(
|
|
1293
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
|
|
926
1294
|
buf[0..5],
|
|
927
1295
|
);
|
|
928
1296
|
stream.reset();
|
|
929
1297
|
|
|
930
|
-
try log.move(p2.ident(4),
|
|
931
|
-
const wrap = N(
|
|
1298
|
+
try log.move(p2.ident(4), M1.Wrap, p1.ident(5), M1.Wrap);
|
|
1299
|
+
const wrap = N(M1.Wrap);
|
|
932
1300
|
try expectLog1(
|
|
933
1301
|
&.{ N(ArgType.Move), 0b1100, wrap, 0b0101, N(Move.From), wrap },
|
|
934
1302
|
buf[0..6],
|
|
935
1303
|
);
|
|
936
1304
|
stream.reset();
|
|
937
1305
|
|
|
938
|
-
try log.move(p2.ident(4),
|
|
1306
|
+
try log.move(p2.ident(4), M1.SkullBash, .{}, null);
|
|
939
1307
|
try log.laststill();
|
|
940
1308
|
try expectLog1(
|
|
941
1309
|
&.{
|
|
942
1310
|
N(ArgType.Move),
|
|
943
1311
|
0b1100,
|
|
944
|
-
N(
|
|
1312
|
+
N(M1.SkullBash),
|
|
945
1313
|
0,
|
|
946
1314
|
N(Move.None),
|
|
947
1315
|
N(ArgType.LastStill),
|
|
@@ -950,13 +1318,13 @@ test "|move|" {
|
|
|
950
1318
|
);
|
|
951
1319
|
stream.reset();
|
|
952
1320
|
|
|
953
|
-
try log.move(p2.ident(4),
|
|
1321
|
+
try log.move(p2.ident(4), M1.Tackle, p1.ident(5), null);
|
|
954
1322
|
try log.lastmiss();
|
|
955
1323
|
try expectLog1(
|
|
956
1324
|
&.{
|
|
957
1325
|
N(ArgType.Move),
|
|
958
1326
|
0b1100,
|
|
959
|
-
N(
|
|
1327
|
+
N(M1.Tackle),
|
|
960
1328
|
0b0101,
|
|
961
1329
|
N(Move.None),
|
|
962
1330
|
N(ArgType.LastMiss),
|
|
@@ -975,8 +1343,8 @@ test "|switch|" {
|
|
|
975
1343
|
try log.switched(p2.ident(3), &snorlax);
|
|
976
1344
|
const par = 0b1000000;
|
|
977
1345
|
var expected: []const u8 = switch (endian) {
|
|
978
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
979
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1346
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
|
|
1347
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
|
|
980
1348
|
};
|
|
981
1349
|
try expectLog1(expected, buf[0..9]);
|
|
982
1350
|
stream.reset();
|
|
@@ -986,8 +1354,8 @@ test "|switch|" {
|
|
|
986
1354
|
snorlax.status = 0;
|
|
987
1355
|
try log.switched(p2.ident(3), &snorlax);
|
|
988
1356
|
expected = switch (endian) {
|
|
989
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
990
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1357
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
|
|
1358
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
|
|
991
1359
|
};
|
|
992
1360
|
try expectLog1(expected, buf[0..9]);
|
|
993
1361
|
stream.reset();
|
|
@@ -995,11 +1363,30 @@ test "|switch|" {
|
|
|
995
1363
|
snorlax.hp = 400;
|
|
996
1364
|
try log.switched(p2.ident(3), &snorlax);
|
|
997
1365
|
expected = switch (endian) {
|
|
998
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
999
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1366
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
|
|
1367
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
|
|
1000
1368
|
};
|
|
1001
1369
|
try expectLog1(expected, buf[0..9]);
|
|
1002
1370
|
stream.reset();
|
|
1371
|
+
|
|
1372
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1373
|
+
blissey.level = 91;
|
|
1374
|
+
blissey.hp = 200;
|
|
1375
|
+
blissey.stats.hp = 400;
|
|
1376
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1377
|
+
try log.switched(p2.ident(3), &blissey);
|
|
1378
|
+
expected = &(.{
|
|
1379
|
+
N(ArgType.Switch),
|
|
1380
|
+
0b1011,
|
|
1381
|
+
N(S2.Blissey),
|
|
1382
|
+
N(gen2.Gender.Female),
|
|
1383
|
+
91,
|
|
1384
|
+
} ++ switch (endian) {
|
|
1385
|
+
.Big => .{ 0, 200, 1, 144, par },
|
|
1386
|
+
.Little => .{ 200, 0, 144, 1, par },
|
|
1387
|
+
});
|
|
1388
|
+
try expectLog2(expected, buf[0..10]);
|
|
1389
|
+
stream.reset();
|
|
1003
1390
|
}
|
|
1004
1391
|
|
|
1005
1392
|
test "|cant|" {
|
|
@@ -1007,8 +1394,8 @@ test "|cant|" {
|
|
|
1007
1394
|
try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
|
|
1008
1395
|
stream.reset();
|
|
1009
1396
|
|
|
1010
|
-
try log.disabled(p1.ident(2),
|
|
1011
|
-
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(
|
|
1397
|
+
try log.disabled(p1.ident(2), M1.Earthquake);
|
|
1398
|
+
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
|
|
1012
1399
|
stream.reset();
|
|
1013
1400
|
}
|
|
1014
1401
|
|
|
@@ -1118,9 +1505,9 @@ test "|-status|" {
|
|
|
1118
1505
|
try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
|
|
1119
1506
|
stream.reset();
|
|
1120
1507
|
|
|
1121
|
-
try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR),
|
|
1508
|
+
try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR), M1.BodySlam);
|
|
1122
1509
|
try expectLog1(
|
|
1123
|
-
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(
|
|
1510
|
+
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
|
|
1124
1511
|
buf[0..5],
|
|
1125
1512
|
);
|
|
1126
1513
|
stream.reset();
|
|
@@ -1191,8 +1578,8 @@ test "|-hitcount|" {
|
|
|
1191
1578
|
}
|
|
1192
1579
|
|
|
1193
1580
|
test "|-prepare|" {
|
|
1194
|
-
try log.prepare(p2.ident(2),
|
|
1195
|
-
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(
|
|
1581
|
+
try log.prepare(p2.ident(2), M1.Dig);
|
|
1582
|
+
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
|
|
1196
1583
|
stream.reset();
|
|
1197
1584
|
}
|
|
1198
1585
|
|
|
@@ -1249,12 +1636,12 @@ test "|-start|" {
|
|
|
1249
1636
|
);
|
|
1250
1637
|
stream.reset();
|
|
1251
1638
|
|
|
1252
|
-
try log.startEffect(p1.ident(2), .Disable,
|
|
1253
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(
|
|
1639
|
+
try log.startEffect(p1.ident(2), .Disable, M1.Surf);
|
|
1640
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
|
|
1254
1641
|
stream.reset();
|
|
1255
1642
|
|
|
1256
|
-
try log.startEffect(p1.ident(2), .Mimic,
|
|
1257
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(
|
|
1643
|
+
try log.startEffect(p1.ident(2), .Mimic, M1.Surf);
|
|
1644
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
|
|
1258
1645
|
stream.reset();
|
|
1259
1646
|
}
|
|
1260
1647
|
|
|
@@ -1273,21 +1660,25 @@ test "|-ohko|" {
|
|
|
1273
1660
|
try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
|
|
1274
1661
|
stream.reset();
|
|
1275
1662
|
}
|
|
1663
|
+
|
|
1276
1664
|
test "|-crit|" {
|
|
1277
1665
|
try log.crit(p2.ident(5));
|
|
1278
1666
|
try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
|
|
1279
1667
|
stream.reset();
|
|
1280
1668
|
}
|
|
1669
|
+
|
|
1281
1670
|
test "|-supereffective|" {
|
|
1282
1671
|
try log.supereffective(p1.ident(1));
|
|
1283
1672
|
try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
|
|
1284
1673
|
stream.reset();
|
|
1285
1674
|
}
|
|
1675
|
+
|
|
1286
1676
|
test "|-resisted|" {
|
|
1287
1677
|
try log.resisted(p2.ident(2));
|
|
1288
1678
|
try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
|
|
1289
1679
|
stream.reset();
|
|
1290
1680
|
}
|
|
1681
|
+
|
|
1291
1682
|
test "|-immune|" {
|
|
1292
1683
|
try log.immune(p1.ident(3), .None);
|
|
1293
1684
|
try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
|
|
@@ -1297,8 +1688,125 @@ test "|-immune|" {
|
|
|
1297
1688
|
try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
|
|
1298
1689
|
stream.reset();
|
|
1299
1690
|
}
|
|
1691
|
+
|
|
1300
1692
|
test "|-transform|" {
|
|
1301
1693
|
try log.transform(p2.ident(4), p1.ident(5));
|
|
1302
1694
|
try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
|
|
1303
1695
|
stream.reset();
|
|
1304
1696
|
}
|
|
1697
|
+
|
|
1698
|
+
test "|drag|" {
|
|
1699
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1700
|
+
blissey.level = 91;
|
|
1701
|
+
blissey.hp = 200;
|
|
1702
|
+
blissey.stats.hp = 400;
|
|
1703
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1704
|
+
try log.drag(p2.ident(3), &blissey);
|
|
1705
|
+
const par = 0b1000000;
|
|
1706
|
+
const expected = &(.{
|
|
1707
|
+
N(ArgType.Drag),
|
|
1708
|
+
0b1011,
|
|
1709
|
+
N(S2.Blissey),
|
|
1710
|
+
N(gen2.Gender.Female),
|
|
1711
|
+
91,
|
|
1712
|
+
} ++ switch (endian) {
|
|
1713
|
+
.Big => .{ 0, 200, 1, 144, par },
|
|
1714
|
+
.Little => .{ 200, 0, 144, 1, par },
|
|
1715
|
+
});
|
|
1716
|
+
try expectLog2(expected, buf[0..10]);
|
|
1717
|
+
stream.reset();
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
test "|-item|" {
|
|
1721
|
+
try log.item(p2.ident(2), I2.GoldBerry, p1.ident(4));
|
|
1722
|
+
try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
|
|
1723
|
+
stream.reset();
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
test "|-enditem|" {
|
|
1727
|
+
try log.enditem(p1.ident(1), I2.BerserkGene, .None);
|
|
1728
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
|
|
1729
|
+
stream.reset();
|
|
1730
|
+
|
|
1731
|
+
try log.enditem(p2.ident(4), I2.PRZCureBerry, .Eat);
|
|
1732
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
|
|
1733
|
+
stream.reset();
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
test "|-cureteam|" {
|
|
1737
|
+
try log.cureteam(p2.ident(5));
|
|
1738
|
+
try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
|
|
1739
|
+
stream.reset();
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
test "|-sethp|" {
|
|
1743
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
|
|
1744
|
+
blissey.hp = 612;
|
|
1745
|
+
try log.sethp(p2.ident(2), &blissey, .Silent);
|
|
1746
|
+
var expected: []const u8 = switch (endian) {
|
|
1747
|
+
.Big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
|
|
1748
|
+
.Little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
|
|
1749
|
+
};
|
|
1750
|
+
try expectLog2(expected, buf[0..8]);
|
|
1751
|
+
stream.reset();
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
test "|-setboost|" {
|
|
1755
|
+
try log.setboost(p2.ident(6), 6);
|
|
1756
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
|
|
1757
|
+
stream.reset();
|
|
1758
|
+
|
|
1759
|
+
try log.setboost(p2.ident(3), 2);
|
|
1760
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
|
|
1761
|
+
stream.reset();
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
test "|-copyboost|" {
|
|
1765
|
+
try log.copyboost(p2.ident(3), p1.ident(6));
|
|
1766
|
+
try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
|
|
1767
|
+
stream.reset();
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
test "|-sidestart|" {
|
|
1771
|
+
try log.sidestart(.P2, .Reflect);
|
|
1772
|
+
try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
|
|
1773
|
+
stream.reset();
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
test "|-sideend|" {
|
|
1777
|
+
try log.sideend(.P2, .LightScreen);
|
|
1778
|
+
try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
|
|
1779
|
+
stream.reset();
|
|
1780
|
+
|
|
1781
|
+
try log.spikesend(.P1, M2.RapidSpin, p1.ident(3));
|
|
1782
|
+
try expectLog2(&.{
|
|
1783
|
+
N(ArgType.SideEnd),
|
|
1784
|
+
0,
|
|
1785
|
+
N(Side.Spikes),
|
|
1786
|
+
N(M2.RapidSpin),
|
|
1787
|
+
0b0011,
|
|
1788
|
+
}, buf[0..5]);
|
|
1789
|
+
stream.reset();
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
test "|-singlemove|" {
|
|
1793
|
+
try log.singlemove(p2.ident(2), M2.DestinyBond);
|
|
1794
|
+
try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
|
|
1795
|
+
stream.reset();
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
test "|-singleturn|" {
|
|
1799
|
+
try log.singleturn(p1.ident(3), M2.Protect);
|
|
1800
|
+
try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
|
|
1801
|
+
stream.reset();
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
test "|-weather|" {
|
|
1805
|
+
try log.weather(W2.Rain, .Upkeep);
|
|
1806
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
|
|
1807
|
+
stream.reset();
|
|
1808
|
+
|
|
1809
|
+
try log.weather(W2.None, .None);
|
|
1810
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
|
|
1811
|
+
stream.reset();
|
|
1812
|
+
}
|